为什么option.fold的结果是一个函数



评估选项的数据时,我尝试使用 fold[B](ifEmpty: => B)(f: A => B): B,但是我对结果有些困惑:

scala> Some(1).fold(() => "empty")(d => d.toString)
res5: () => String = <function0>
scala> Some(1).fold(() => "empty")(d => d.toString)()
res6: String = 1

此方法的源代码:

  @inline final def fold[B](ifEmpty: => B)(f: A => B): B =
    if (isEmpty) ifEmpty else f(this.get)

我期望结果是String,但是有<function0>,为什么?

==================

我试图用以下代码嘲笑这种情况:

case class Demo(size: Int)
// version 1, with the same fold method as Option
case class X [A <: Demo](data: A) {
    def fold[B](ifEmpty: => B)(f: A => B): B = {
        if(data.size < 3) ifEmpty else f(data)
    }
}
val demo = Demo(2)
val x = X(demo)
x.fold(() => "empty")(d => d.toString)   // the result is a function
// version 2
case class X [A <: Demo](data: A) {
    def fold[B](g: A => B)(f: A => B): B = {
        if(data.size < 3) g(data) else f(data)
    }
}
x.fold(g => g.toString)(f => f.toString)   // the result is a String

根据演示,结果似乎受到Scala类型推理的影响,是吗?

,因为您将 () => "empty"作为第一个参数,这是类型() => String的函数;这就是B类型的目标。请注意, ifEmpty参数是呼叫的参数。

如果您不希望B() => String,而只是String,请尝试以下方法:

Some(1).fold("empty")(d => d.toString)

在您的编辑之后添加:版本1和版本2演示之间的主要区别是,在版本1中, ifEmpty是一个呼叫参数,在版本2中, g不是一个名称参数,但是类型A => B的函数。

最新更新