此代码编译时出现错误:
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
}
在这两种情况下,在模式匹配表达式中我们都知道i and b are Int and Boolean。为什么第一个示例编译失败而第二个示例编译成功?
第一种情况是不合理的,因为你低估了 Scala 类型系统中类型的多样性。如果当我们采取case i:Int
我们知道的分支T
was Int
,或者至少是一个超类型Int
。但不一定是这样!例如。它可能是42.type https://docs.scala-lang.org/sips/42.type.html or a 标记类型 http://eed3si9n.com/learning-scalaz/Tagged+type.html.
第二种情况不存在这样的问题,因为从IntExpr <: Expr[T]
,编译器does know T
必须完全是Int
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)