2013-12-22 74 views
7

考虑到这一功能:泛型类型的隐式转换?

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]. 

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

+0

确实很奇怪。 'val a = new TruthTeller(List(1,2,3))'可以。当你移除'type T'并使用'imp ev:S <: Kigyo

+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 

至于变通方法有很多,您可以在答案中使用higher-kinded,或者例如从seq参数中强制推荐T

// 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 
+0

感谢您指出这是一个错误! –

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 

但我真的想知道为什么原来的代码无法正常工作。