斯卡拉查看应用程序的益智游戏(Scala view application puzzler)

2019-08-03 03:14发布

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

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
                          ^

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

视图是在三种情况下应用。

  1. [这是不相关的。]

  2. 在选择时间与类型TE, 如果选择器不表示T的成员 。 在这种情况下,视图v搜索其适用于E和,其结果包含一个成员名为 。 该搜索继续进行,如隐式参数,其中所述隐式范围T的一个的情况下。 如果找到了这样的图,该选择EM被转换到v(e)中的.m。

  3. 在选择EM(参数)与类型TE, 如果选择器m表示的T一些构件(一个或多个),但是,没有这些构件的适用于参数ARGS。 在这种情况下,视图v搜索其适用于E和,其结果包含方法其适用成参数 。 该搜索继续进行,如隐式参数,其中所述隐式范围T的一个的情况下。 如果找到了这样的图,该选择EM被转换到v(e)中的m(参数)。

因此,我们尝试以下方法,认为它一定是太荒谬了工作:

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

这导致了一些非常奇怪的行为,例如在此解决方法为这个问题 。

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

  1. 有没有(即一个不涉及添加假的方法用适当的名称)有鉴于上文原来如此正确应用一个简单的方法?
  2. 有人可以提供占该行为规范的阅读?
  3. 假设这是预期的行为,这有什么意义呢?

我也很感激这个问题,我没有多少运气与谷歌的前面讨论的任何链接。

Answer 1:

对于大家的参考,这只能是一个错误。 你知道的方式是错误信息:

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

列表[A]是不是一个真正的类型 - 这是列表应用到自己的类型参数。 那是不是可以要求,因为它不是可以表示一个类型的类型。

[编辑 - 这是太早了,谁知道我在说什么。 忽略上面,但你仍然可以按照链接]

造成这种情况的相关票https://issues.scala-lang.org/browse/SI-6472 。



Answer 2:

这似乎是一个错误,所以我的答案是:

  1. 搜索报道对Scala编译器一个simliar错误,如果没有找到,报告新的错误https://issues.scala-lang.org/
  2. 规范的一部分似乎并不在此情况下重要,因为它不谈论类型推断
  3. 没有任何意义,我

PS。 在2.8.1您添加虚拟的方法来酒吧的解决方法并不能使它编译。



Answer 3:

与此更换您的Foo:

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

它的工作原理,这也使得相当多的我更有意义,因为你是绝对不感兴趣A.



Answer 4:

你的隐式转换似乎是在做什么你告诉它做的事。

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

它寻找一个“A”型。

为了使这项工作,你想给你的方式(我认为),而不是定义上,你可以做它的功能性状的观点。

trait Foo { def howMany[A](xs: List[A]) = xs.size }
trait Bar
implicit def bar2foo[A](bar: Bar) = new Foo{}
val bar = new Bar {}
val stuff = List(1, 2, 3)

那么就应该给你你想要的结果。

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)

我个人认为定义它的功能是清洁。



Answer 5:

这虽然难看,似乎工作:

(bar: Foo[Int]) howMany stuff


文章来源: Scala view application puzzler