在Scala中检查涉及存在式的类型的相等性
我在写一个函数的形式在Scala中检查涉及存在式的类型的相等性,scala,existential-type,Scala,Existential Type,我在写一个函数的形式 def test[A,B](a: A, b: B)(implicit eq: A =:= B): Unit = ... 其中我需要证明A和B类型相同的证据 我希望test(a,a)形式的调用能够为任何a编译,但当a的类型涉及存在性时,情况似乎并非如此,比如 case class Foo[T](c: T) val l = List(Foo(1), Foo(1.0F), Foo(0.0)) // Inferred type: List[Foo[_ >: Double w
def test[A,B](a: A, b: B)(implicit eq: A =:= B): Unit = ...
其中我需要证明A
和B
类型相同的证据
我希望test(a,a)
形式的调用能够为任何a
编译,但当a
的类型涉及存在性时,情况似乎并非如此,比如
case class Foo[T](c: T)
val l = List(Foo(1), Foo(1.0F), Foo(0.0)) // Inferred type: List[Foo[_ >: Double with Float with Int <: AnyVal]]
test(l.head, l.head) // Does not compile, error like: Cannot prove that Foo[_7] =:= Foo[_7].
案例类Foo[T](c:T)
val l=List(Foo(1)、Foo(1.0F)、Foo(0.0))//推断类型:List[Foo[\u>:Double with Float with IntImplicit=:=适用于存在类型
scala> implicitly[Foo[_ <: Int] =:= Foo[_ <: Int]]
res0: =:=[Foo[_ <: Int],Foo[_ <: Int]] = <function1>
scala> implicitly[Foo[_ <: Int] =:= Foo[_]]
<console>:10: error: Cannot prove that Foo[_ <: Int] =:= Foo[_].
implicitly[Foo[_ <: Int] =:= Foo[_]]
^
可以使用类型别名解决此问题:
scala> case class Foo[A](a: A) {type X = A}
defined class Foo
scala> val l = List(Foo(1), Foo(1.0F), Foo(0.0)) // Inferred type: List[Foo[_ >: Double with Float with Int <: AnyVal]]
l: List[Foo[_ >: Double with Float with Int <: AnyVal]] = List(Foo(1), Foo(1.0), Foo(0.0))
scala> val k = l.head
k: Foo[_ >: Double with Float with Int <: AnyVal] = Foo(1)
scala> implicitly[k.X =:= k.X]
res15: =:=[_ >: Double with Float with Int <: AnyVal, _ >: Double with Float with Int <: AnyVal] = <function1>
scala> implicitly[k.X =:= _ >: Double with Float with Int <: AnyVal]
res16: =:=[_ >: Double with Float with Int <: AnyVal, _ >: Double with Float with Int <: AnyVal] = <function1>
scala>case类Foo[A](A:A){type X=A}
定义类Foo
scala>val l=List(Foo(1)、Foo(1.0F)、Foo(0.0))//推断类型:List[Foo[\u>:Double with Float with Int:Double with Float with Int val k=l.head
k:Foo[\u>:Double,带浮点,隐式带Int[k.X=:=k.X]
res15:=:=[\u>:Double with Float with Int:Double with Float with Int隐式[k.X=:=\u>:Double with Float with Int:Double with Float with Int:Double with Float with Int:Double with Float with Int回答得很好。但我仍然不明白为什么它在这个问题中失败。你这么说是什么意思:它在这里被解除绑定
而且如果它有效:隐式地[Foo][\u>:Double with Float with Int:Double with Float with Int test函数在A,B存在时对它们进行某种编译时擦除(我认为可以在编译器中修复它),因此A和B变成了_7-对于这种内部存在类型,没有隐式可能,所以隐式[\u 7=:=\u 7]失败。在您的示例中,存在类型是已知的,因此它工作正常。def t[A,B](n:A,x:B)=println(n+“”+x)t(l.head,l.head)
有效。我仍然不完全理解注释中的原因:)。从我看来,这似乎是一个编译器警告。“n是一个非推断的类型表示-它只是在解析隐式时没有被推断出来。实际上,在函数中调用什么并不重要,因为即使隐式也不适用于泛型类型。
scala> case class Foo[A](a: A) {type X = A}
defined class Foo
scala> val l = List(Foo(1), Foo(1.0F), Foo(0.0)) // Inferred type: List[Foo[_ >: Double with Float with Int <: AnyVal]]
l: List[Foo[_ >: Double with Float with Int <: AnyVal]] = List(Foo(1), Foo(1.0), Foo(0.0))
scala> val k = l.head
k: Foo[_ >: Double with Float with Int <: AnyVal] = Foo(1)
scala> implicitly[k.X =:= k.X]
res15: =:=[_ >: Double with Float with Int <: AnyVal, _ >: Double with Float with Int <: AnyVal] = <function1>
scala> implicitly[k.X =:= _ >: Double with Float with Int <: AnyVal]
res16: =:=[_ >: Double with Float with Int <: AnyVal, _ >: Double with Float with Int <: AnyVal] = <function1>