Scala View 应用程序谜题

标签 scala types implicits

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

trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar

以及从第二个到第一个的隐式转换:

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

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

val bar = new Bar {}
val stuff = List(1, 2, 3)

现在我希望以下内容能够发挥作用:

bar howMany stuff

但事实并非如此:

scala> bar howMany stuff
<console>:13: error: type mismatch;
 found   : List[Int]
 required: List[A]
              bar howMany stuff
                          ^

所以我们去the spec ,其中有这样的说法(粗体强调是我的):

Views are applied in three situations.

  1. [Isn't relevant here.]

  2. In a selection e.m with e of type T, if the selector m does not denote a member of T. In this case, a view v is searched which is applicable to e and whose result contains a member named m. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T. If such a view is found, the selection e.m is converted to v(e).m.

  3. In a selection e.m(args) with e of type T, if the selector m denotes some member(s) of T, but none of these members is applicable to the arguments args. In this case a view v is searched which is applicable to e and whose result contains a method m which is applicable to args. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T. If such a view is found, the selection e.m is converted to 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)

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

scala> bar howMany stuff
res0: Int = 3

这会导致一些非常奇怪的行为,例如 this workaround对于 this problem .

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

  1. 是否有一种直接的方法(即不涉及添加具有适当名称的虚假方法的方法)来在上述原始情况下正确应用 View ?
  2. 有人可以提供解释此行为的规范吗?
  3. 假设这是预期的行为,它有任何意义吗?

我也希望能提供有关此问题之前讨论的任何链接 - 我在 Google 上的运气不太好。

最佳答案

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

<console>:13: error: type mismatch;
 found   : List[Int]
 required: List[A]

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

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

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

关于Scala View 应用程序谜题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13515169/

相关文章:

scala - Intellij IDEA - 输出路径 ...\project\target\idea-classes 与源根目录​​相交。仅清理由构建创建的文件

scala - Play 框架中的集成测试

c - 如何编写处理大数的解决方案?

hash - 是否可以为整个整数范围实现通用哈希?

scala - Scala 中的方法与函数和隐式

scala - 如何使用 Akka Streams 和 HTTP 将 HTTP 资源下载到文件?

scala - Haskell 的 mapM 相当于 Scala 猫

types - 为什么存储在 Float 数据类型中的数据被视为近似值?

scala - 从非协变类的实例创建协变类型类的实例

scala - 构造一个可重写的隐式