Scala 抽象参数参数化的单态类型模式匹配
如果有人能在这两个类型参数之间的奇怪转换过程中详细解释编译器的逻辑,我将不胜感激Scala 抽象参数参数化的单态类型模式匹配,scala,Scala,如果有人能在这两个类型参数之间的奇怪转换过程中详细解释编译器的逻辑,我将不胜感激 def unsafeCoerce[A, B]: A => B = { val a = implicitly[A =:= A] implicitly[B =:= B] match { case _: a.type => implicitly[A =:= B] } } 可以执行 scala> Some(unsafeCoerce[String, Int]("hi")) res0:
def unsafeCoerce[A, B]: A => B = {
val a = implicitly[A =:= A]
implicitly[B =:= B] match {
case _: a.type => implicitly[A =:= B]
}
}
可以执行
scala> Some(unsafeCoerce[String, Int]("hi"))
res0: Some[Int] = Some(hi)
为什么编译器允许隐式编译[A=:=B]
这个例子取自
问题是为什么我们可以证明。例如,我们不能证明String是Int,但可以隐式地证明[B=:=B]是a.type
我们不能。隐式[B=:=B]
是a.type
或不是(即隐式[B=:=B]eq a
为真或非真)。守则说,基本上:
B=:=B
和A=:=A
,因此A
和B
是相同的(因为=:=
是不变的),所以隐式地[A=:=B]
编译MatchError
tpEquals
时发生的情况,例如
object =:= {
implicit def tpEquals[A]: A =:= A = new =:=[A,A] {
def apply(x: A): A = x
}
}
事实上,正如我的评论所说,这也会发生在
unsafeccerce[String,String](“hi”)
上,因为对的两个调用会隐式地创建两个不同的实例。。我试过这个。Dotty不会编译:“无法证明A=:=B.”@jwvh它似乎无法在较新版本的scala(2.11及更高版本)上编译。对于版本2.10.6,它的工作原理如问题中所述。链接页面已经给出了答案:“因此,如果我们能够证明其他东西具有singleton类型x.type,我们还将证明它共享所有x类型”。问题是,unsafeccerce[String,Int](“hi”)
“应该”抛出一个异常(实际上,unsafecce[String,String](“hi”)
),但假设我们有a.type<=:=[a,a]和=:=[B,B]。编译器允许我们检查=:=[B,B]是否是a.type([a,a])的等式。。。但是它们绝对不相等,因为它们由不同的类型参数参数参数化(在我们的例子中,它们是抽象的)。所以这就是为什么我说,这和编译器允许这个检查“5 match{case}:String=>…}”是一样的。。但是它甚至没有被编译。或者类似的东西也没有被编译。class A[A]val s=new A[String]val i=new A[Int]s match{case}我想这是允许编译的,只是因为参数的抽象性质。所以编译器会忽略这些参数,并将.type视为=:=[Object,Object]的子类型。对于=:=[B,B]“=:=[B,B]是a.type([a,a])的等式”=:=[B,B]
是一种类型,它不能是任何类型的eq
隐式地[B,B]
是这种类型的值,编译器不能排除它也是=:=[a,a]
(如果a
和B
是相同的)。在第二条注释中,编译器知道a[String]
永远不能是a[Int]
因此它不能是a.type
:类型不兼容。