Scala视图应用程序谜题
假设我们有以下两个特点:Scala视图应用程序谜题,scala,types,implicits,Scala,Types,Implicits,假设我们有以下两个特点: trait Foo[A] { def howMany(xs: List[A]) = xs.size } trait Bar 以及从第二个到第一个的隐式转换: implicit def bar2foo[A](bar: Bar) = new Foo[A] {} 我们创建一个条和一个整数列表: val bar = new Bar {} val stuff = List(1, 2, 3) 现在,我希望以下方法能够奏效: bar howMany stuff 但事实并非如此
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
以及从第二个到第一个的隐式转换:
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
我们创建一个条和一个整数列表:
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
^
但确实如此(至少在2.9.2和2.10.0-RC2上):
这会导致一些非常奇怪的行为,例如for
我有三个(密切相关的)问题:
是否有一种简单的方法(即,不涉及添加具有适当名称的假方法)可以在上面的原始案例中正确应用视图
有人能提供说明这种行为的规格说明吗
假设这是预期的行为,它有任何意义吗
我也非常感谢与之前关于这个问题的讨论的任何链接——我在谷歌的运气不太好。用以下内容替换您的Foo:
trait Foo[]{def howMany(xs:List[])=xs.size}
它是有效的,这对我来说也更有意义,因为你对a绝对不感兴趣。你的隐式转换似乎正是你告诉它做的
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
将条形图转换为新的Foo[a]
对象。反过来说
scala> bar howMany stuff
<console>:13: error: type mismatch;
found : List[Int]
required: List[A]
bar howMany stuff
然后它会给你你想要的结果
scala> bar howMany stuff
res0: Int = 3
也可以在隐式函数上定义视图
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
implicit def bar2foo[A](bar: Bar) = new Foo[Int] {}
val bar = new Bar {}
val stuff = List(1, 2, 3)
就我个人而言,我认为在函数上定义它更简洁。这似乎是一个bug,因此我的答案是:
搜索针对Scala编译器报告的simliar错误,如果未找到,则报告新错误
规范的这一部分在本例中似乎并不重要,因为它没有讨论类型推断
对我来说没有任何意义
注:在2.8.1中,将虚拟方法添加到Bar中的变通方法无法使其编译。这虽然很难看,但似乎有效:
(bar: Foo[Int]) howMany stuff
供大家参考,这可能只是一个bug。您知道的方式是错误消息:
<console>:13: error: type mismatch;
found : List[Int]
required: List[A]
:13:错误:类型不匹配;
找到:列表[Int]
必需:列表[A]
列表[A]不是实类型-它是应用于自身类型参数的列表。这不是一个需要的类型,因为它不是一个可以表达的类型
[编辑-现在太早了,谁知道我在说什么。忽略上面的内容,但你仍然可以点击链接。]
与此相关的问题是。这在特定的简化情况下有效,但一般来说,我关心的是A
——例如,在问题中链接的Scalaz问题的解决方案中。我想要的是“明显的”行为,即。,对于Foo
的一个
参数,该参数将根据多少个
的参数进行推断。这显然是可能的,因为我可以通过向Bar
添加一个(完全任意定义的)伪howmounty
方法来实现。
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
implicit def bar2foo[A](bar: Bar) = new Foo[Int] {}
val bar = new Bar {}
val stuff = List(1, 2, 3)
(bar: Foo[Int]) howMany stuff
<console>:13: error: type mismatch;
found : List[Int]
required: List[A]