scala 2.10 中的 Option.fold [英] Option.fold in scala 2.10

查看:57
本文介绍了scala 2.10 中的 Option.fold的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下使用 Scala 2.10.0-M7 的会话中:

In the following session with 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}

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

I would expect the compiler find the common supertype (namely A) rather than complaining. Is it the general type inference limitation, or the consequence of the way Option.fold is defined?

谢谢.

推荐答案

结合Scalas类型推断算法和Option.fold定义方式的问题结果.

The problem results of a combination of Scalas type inference algorithm and the way how Option.fold is defined.

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

Scalas type inference works from left to right, this means that it starts with the leftmost symbol to search for a possible type for an expression. Further, for method parameter lists this means, that a generic type is bound to the type filled in by the leftmost parameter list:

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)("")
                      ^

如我们所见,在第一种情况下 Any 被推断,而在第二种情况下会抛出编译器错误,因为 A 的类型受第一个约束参数列表和第二个不能再改变它.

As one can see, in the first case Any is inferred, whereas in the second case a compiler error is thrown because the type of A is bound by the first parameter list and the second one can't change it any more.

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

But in order to get he method call in the question to work, the type of the resulting Option may not defined until the second parameter list is reached. Because this requires a right to left type inference hence the error. This is somewhat identical to 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)
                                               ^

要使代码工作,必须明确指定结果集合的类型,请参阅 @rks 答案一个例子.

To get the code to work one has to explicitly specify the type of the resulting collection, see @rks answer for an example.

请参阅此处的讨论,了解原因的完整说明它被定义为它被定义.简而言之:Option 在很多方面都遵循集合的设计——因此当它的行为方式与集合相同时会更加清晰.

See the discussion here for the full explanation why it is defined as it is defined. In short: Option follows the design of collections in a lot of respects - thus it is more clear when it behaves the same way as collections do.

这篇关于scala 2.10 中的 Option.fold的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆