在模式匹配中使用的抽象类型上键入不匹配

Bog*_*nko 9 generics scala

此代码编译错误:

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 ...
Run Code Online (Sandbox Code Playgroud)

从类型检查角度看,实现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
}
Run Code Online (Sandbox Code Playgroud)

在两种情况下,在模式匹配表达式中,我们知道ibIntBoolean.为什么第一个例子编译失败而第二个例子成功?

Ale*_*nov 6

第一种情况是不合理的,因为您低估了 Scala 类型系统中类型的多样性。如果在我们使用case i:Intbranch 时我们知道TInt,或者至少是 的超类型,那将是有道理的Int。但它不一定是!例如,它可以是42.type标记类型

在第二种情况下没有这样的问题,因为 from IntExpr <: Expr[T],编译器确实知道Tmust 正是Int