【发布时间】:2019-02-27 23:40:52
【问题描述】:
此代码编译时出错:
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 和 b 是 Int 和 Boolean。为什么在第一个示例编译失败而在第二个示例编译成功?
【问题讨论】:
-
我删除了我的答案(这是错误的)。我还发现,如果您从示例中删除显式返回类型,它会编译并运行。如果是
C++preC++17的情况(有编译时泛型,但没有编译时if),我会告诉我方法体对于任何类型T都不正确,如@ 987654327@ 永远不会同时是Int和Boolean。 -
@bobah 因为它推断出返回类型为 AnyVal
-
你的函数只是
def f1[T](e: T) = e。如果你想要一个解决方案,上下文会很有帮助。虽然也许你只是在寻找一个原因 -
@JoelBerkeley 这个问题主要是理论上的,而不是实际的。我正在尝试理解编译逻辑。
-
这似乎取决于模式是值模式还是类型模式。这也失败了
case class Expr[T](v: T); def eval[T](e: Expr[T]): T = e match { case Expr(i: Int) => i; case Expr(b: Boolean) => b }