此代码编译时出现错误:
def f1[T](e: T): T = e match {
case i:Int => i
case b:Boolean => b
}
// type mismatch;
// found : i.type (with underlying type Int)
// required: T
// case i:Int => i ...
从类型检查的角度来看,这段实现 GADT 的代码看起来非常相同,但编译时没有错误:
sealed trait Expr[T]
case class IntExpr(i: Int) extends Expr[Int]
case class BoolExpr(b: Boolean) extends Expr[Boolean]
def eval[T](e: Expr[T]): T = e match {
case IntExpr(i) => i
case BoolExpr(b) => b
}
在模式匹配表达式中的两种情况下,我们都知道 我 和 b 是 国际和 bool .为什么第一个示例编译失败而第二个示例编译成功?
最佳答案
第一种情况是不合理的,因为您低估了 Scala 类型系统中类型的多样性。如果,当我们使用 case i:Int
时,这是有道理的。我们知道的分支 T
是 Int
,或者至少是 Int
的父类(super class)型.但它不一定是!例如。可能是 42.type或 tagged type .
第二种情况没有这样的问题,因为来自 IntExpr <: Expr[T]
,编译器确实知道 T
必须正好 Int
.
关于scala - 模式匹配中使用的抽象类型的类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52479695/