Scala查看应用程序益智游戏

Tra*_*own 13 types scala implicits

假设我们有以下两个特征:

trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
Run Code Online (Sandbox Code Playgroud)

并且从第二个到第一个的隐式转换:

implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
Run Code Online (Sandbox Code Playgroud)

我们创建一个Bar整数列表:

val bar = new Bar {}
val stuff = List(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

现在我希望以下工作:

bar howMany stuff
Run Code Online (Sandbox Code Playgroud)

但它没有:

scala> bar howMany stuff
<console>:13: error: type mismatch;
 found   : List[Int]
 required: List[A]
              bar howMany stuff
                          ^
Run Code Online (Sandbox Code Playgroud)

所以我们去规范,其中有这样一段话(强调用粗体是我的):

视图适用于三种情况.

  1. [这里不相关.]

  2. 在一个选择的EMË类型的Ť,如果选择器并不表示的成员Ť.在这种情况下,搜索视图v,其适用于e并且其结果包含名为m的成员.搜索按照隐式参数的情况进行,其中隐式范围是T的一个.如果找到这样的视图,则将选择em转换为v(e).m.

  3. 在选择EM(参数)Ë类型的Ť,如果选择器表示的一些构件(一个或多个)Ť,但没有这些构件的适用于参数ARGS.在这种情况下,搜索适用于e的视图v,其结果包含 适用于args的方法m.搜索按照隐式参数的情况进行,其中隐式范围是T的一个.如果找到这样的视图,则将选择em转换为 v(e).m(args).

所以我们尝试以下方法,认为工作必须太荒谬:

trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar { def howMany = throw new Exception("I don't do anything!") }

implicit def bar2foo[A](bar: Bar) = new Foo[A] {}

val bar = new Bar {}
val stuff = List(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

但确实如此(至少在2.9.2和2.10.0-RC2上):

scala> bar howMany stuff
res0: Int = 3
Run Code Online (Sandbox Code Playgroud)

这会导致一些非常奇怪的行为,例如在此问题的解决方法中.

我有三个(密切相关的)问题:

  1. 是否有一种简单的方法(即,不涉及添加具有适当名称的假方法)以在上面的原始案例中正确应用视图?
  2. 有人可以提供解释此行为的规范吗?
  3. 假设这是预期的行为,它是否有任何意义?

我也很欣赏以前关于这个问题的讨论的任何链接 - 我对Google没有太多好运.

psp*_*psp 1

供大家参考,这只能是一个bug。您知道的方式是错误消息:

<console>:13: error: type mismatch;
 found   : List[Int]
 required: List[A]
Run Code Online (Sandbox Code Playgroud)

List[A] 不是真正的类型 - 它是应用于其自己的类型参数的 List。这不是一种需要的类型,因为它不是一种可以表达的类型。

[编辑-现在还为时过早,谁知道我在说什么。忽略上述内容,但您仍然可以点击链接。]

相关的票证是https://issues.scala-lang.org/browse/SI-6472