为什么即使明确调用该函数,以下隐式转换也不起作用?
scala> implicit def view[A, C](xs: C)(implicit ev: C <:< Iterable[A]) = new { def bar = 0 }
view: [A, C](xs: C)(implicit ev: <:<[C,scala.collection.immutable.Iterable[A]])java.lang.Object{def bar: Int}
scala> List(1) bar
<console>:147: error: Cannot prove that List[Int] <:< scala.collection.immutable.Iterable[A].
List(1) bar
^
scala> view(List(1)) bar
res37: Int = 0
答案 0 :(得分:0)
我并没有真正回答你的问题(例如,我正在回答&#34;我如何做这项工作&#34;但不是&#34;为什么它不起作用&#34; 34);无论如何,希望这将有助于其他人在回答方面取得一些进展。
所以......在第一种情况下,假设C是List [Int],编译器无法正确推断出A是Int。老实说,我更加惊讶的是,明确地传递List实际上是有效的,因为A和C之间的关系是间接的(你有A和C,因为C是Iterable [A]的子类型,因为C是a列出[Int],然后A必须是一个Int;不是一个非常简单的推理......)。
你可以通过更清楚地了解C和A之间的关系来使其发挥作用,如下所示:
scala> implicit def view[A, C[A]](xs: C[A])(implicit ev: C[A] <:< Iterable[A]) =
new { def bar = 0 }
view: [A, C[A]](xs: C[A])(implicit ev: <:<[C[A],Iterable[A]])java.lang.Object{def bar: Int}
scala> List(1) bar
res0: Int = 0
或(鉴于您未使用A):
scala> implicit def view[C](xs: C)(implicit ev: C <:< Iterable[_]) =
new { def bar = 0 }
scala> List(1) bar
res1: Int = 0
答案 1 :(得分:0)
简单地说,正如错误消息所示,它无法推断A
。编译器没有信息可以用来推断A
必须是什么,所以必须假设它可以是任何东西。
您可以反驳它可以从A
推断出C <:< Iterable[A]
,但这样可以解决问题:不使用<:<
检查约束,而是使用约束来推断出A
的类型!那个逻辑不合理。