泛型类型的隐式转换?

时间:2013-12-22 12:03:45

标签: scala implicit-conversion

考虑这个功能:

def justTrue[T, S](seq: S)(implicit ev: S <:< Seq[T]) = true
justTrue(List(1,2,3))
>> true

有效。但为什么不能将相同的签名用作隐式转换?

implicit class TruthTeller[T, S](seq: S)(implicit ev: S <:< Seq[T]) {
  def justTrue = true
}
List(1,2,3).justTrue
>> error: Cannot prove that List[Int] <:< Seq[T].

隐式转换不是一个函数吗?

2 个答案:

答案 0 :(得分:6)

您完全正确,这应该在隐式def / class中同样有效。

这是一个错误,其中类型参数意外地从隐式视图的参数中保留了类型推断:

SI-7944: type variables escape into the wild

现在已修复至2.11.0-M7:

Welcome to Scala version 2.11.0-M7 (OpenJDK 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :pa
// Entering paste mode (ctrl-D to finish)
implicit class TruthTeller[T, S](seq: S)(implicit ev: S <:< Seq[T]) {
  def justTrue = true
}
List(1,2,3).justTrue
// Exiting paste mode, now interpreting.

defined class TruthTeller
res0: Boolean = true

至于解决方法,有很多,您可以在答案中使用更高级的,或者例如从T参数强制推断seq

// the implicit ev isn't even needed here anymore
// but I am assuming the real use case is more complex
implicit class TruthTeller[T, S](seq: S with Seq[T])(implicit ev: S <:< Seq[T]) {
  def justTrue = true
}
// S will be inferred as List[Int], and T as Int
List(1,2,3).justTrue

答案 1 :(得分:0)

我找到的最佳解决方案:

import scala.language.higherKinds
implicit class TruthTeller[T, S[T] <: Seq[T]](seq: S[T]) {
  def justTrue = true
}
List(1,2,3).justTrue
>> true

但我真的想知道为什么原始代码不起作用。