【发布时间】:2019-08-31 17:24:06
【问题描述】:
考虑这段代码:
trait TypeOr[E, F] {
type T
}
implicit def noneq2[E, F](implicit ev: E =!= F): TypeOr[E, F] = new TypeOr[E, F] {
type T = (E, F)
}
sealed trait Error[+E, +A]
case class Err[E, A](e: Error[E, A]) {
def combine[B, F](f: A => Error[F, B])(implicit ev: TypeOr[E, F]): Error[ev.T, B] = ???
}
val result = Err(null.asInstanceOf[Error[Int, Int]]).combine(_ => null.asInstanceOf[Error[String, String]])
到目前为止一切顺利。根据上面的定义,我得出结论,结果的扩展类型如下:
val itsType: Error[(Int, String), String] = result
但显然不是,因为编译器会回复:
found : returnerror.Comb.Error[returnerror.Comb.TypeOr[Int,String]#T,String]
required: returnerror.Comb.Error[(Int, String),String]
val itsType: Error[(Int, String), String] = result
是否可以找出表达式的简化扩展类型?我无法从编译器获取此信息,我尝试在擦除阶段之前打印 AST,但扩展类型仍然不存在。
【问题讨论】:
-
能否提供
returnerror.TypeOr的代码? -
编译器不相信
TypeOr和Tuple2是等价的。他们应该是吗? -
我特别感兴趣的是,编译器认为这些类型不仅仅是解决这个特殊情况。我尝试打印编译器阶段,但它不会在任何阶段打印扩展类型。
-
@coubeatczech 尝试将
scalacOptions in Compile ++= Seq("-Xprint-types", "-Xprint:typer")添加到 build.sbt。
标签: scala types implicit type-level-computation