scala 2.10中的Option.fold

ven*_*hka 4 scala scala-2.10

在随后的scala 2.10.0-M7会话中:

scala> trait A
defined trait A
scala> class B extends A
defined class B
scala> class C extends A
defined class C
scala> Some(0).fold(new B){_=>new C}
<console>:11: error: type mismatch;
 found   : C
 required: B
              Some(0).fold(new B){_=>new C}
Run Code Online (Sandbox Code Playgroud)

我希望编译器找到常见的超类型(即A)而不是抱怨.是一般的类型推理限制,还是Option.fold定义方式的结果?

谢谢.

kir*_*uku 10

Scalas类型推理算法与Option.fold定义方式相结合的问题结果.

Scalas类型推断从左到右工作,这意味着它从最左边的符号开始,以搜索表达式的可能类型.此外,对于方法参数列表,这意味着泛型类型绑定到最左边的参数列表填充的类型:

scala> def meth[A](a1: A, a2: A) = (a1, a2)
meth: [A](a1: A, a2: A)(A, A)

scala> meth(1, "")
res7: (Any, Any) = (1,"")

scala> def meth[A](a1: A)(a2: A) = (a1, a2)
meth: [A](a1: A)(a2: A)(A, A)

scala> meth(1)("")
<console>:10: error: type mismatch;
 found   : String("")
 required: Int
              meth(1)("")
                      ^
Run Code Online (Sandbox Code Playgroud)

可以看出,在第一种情况下Any是推断的,而在第二种情况下,抛出编译器错误,因为类型A由第一个参数列表绑定而第二个不能再改变它.

但是为了使问题中的方法调用起作用,在Option达到第二个参数列表之前,可能不会定义结果的类型.因为这需要从右到左类型推断因此错误.这有点相同List.fold:

scala> List(1).foldLeft(Nil)((xs,x) => x::xs)
<console>:8: error: type mismatch;
 found   : List[Int]
 required: scala.collection.immutable.Nil.type
              List(1).foldLeft(Nil)((xs,x) => x::xs)
                                               ^
Run Code Online (Sandbox Code Playgroud)

要使代码生效,必须明确指定生成的集合的类型,有关示例,请参阅@rks answer.

请参阅此处的讨论,以获得完整解释为何定义它的定义.简而言之:Option在许多方面遵循集合的设计 - 因此,当它的行为与集合的行为相同时更加清晰.