Как типы проходят через сопоставления с образцами в Scala?
Этот гист (частичный порт Scala этого интерпретатора без тегов Haskell) компилируется с scalac
2.11.1, но терпит неудачу с более новым 2.11.6:
typechecker.scala:55: error: type mismatch;
found : Expr[B] where type B
required: Expr[Int]
case (lhs ::: RInt, rhs ::: RInt) => Add(lhs, rhs) ::: RInt
...
Как scalac
распространять типы через совпадения шаблонов :::
? Что изменилось с 2.11.1
в 2.11.6
? Я пытался смотреть, глядя на вывод scalac -print
а также scalac -Xprint-types
но не нашел их полезными.
Смотрите суть для полного кода, но, примерно, мы имеем
// ADT for untyped expressions
sealed trait UExpr
case class UAdd(lhs: UExpr, rhs: UExpr) extends UExpr
// GADT for typed expressions
sealed trait Expr[T]
case class Add(lhs: Expr[Int], rhs: Expr[Int]) extends Expr[Int]
// Reification of types
sealed trait RType[T]
case object RInt extends RType[Int]
// Expression annotated with reified type
class :::[A,B](val expr: Expr[A], val typ: RType[B])(implicit witness: A === B)
object ::: {
def apply =
...
def unapply =
...
}
// typechecker from UExpr to Expr
def typed(uexpr: UExpr): Option[:::[_,_]] = uexpr match {
case UAdd(l, r) => typed(l, r) collect {
// vvvvvvvv HERE vvvvvvvv
case (lhs ::: RInt, rhs ::: RInt) => Add(lhs, rhs) ::: RInt
// ^^^^^^^^ HERE ^^^^^^^^
}
}
// helper for typing two expressions
def typed(lhs: UExpr, rhs: UExpr): Option[(:::[_,_], :::[_,_])] =
...