模式匹配中使用的抽象类型的类型不匹配

博格丹·瓦库连科

这段代码编译时出现错误:

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
}

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

阿列克谢·罗曼诺夫(Alexey Romanov)

第一种情况是不正确的,因为您低估了Scala类型系统中的各种类型。如果我们在case i:Int分支时知道TInt,或者至少是的超型,这是有道理Int但这不是必须的!例如,可以是42.type标记的type

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章