0

我想确定由语法树表示的表达式是否tree1属于tree2同一类型。我尝试使用来自的类型检查方法这样做scala.tools.reflect.ToolBox,但它似乎与实际的 Scala 类型不一致。

在这里我创建了工具箱:

scala> val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] 
              = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@1ad29bfd

它报告类型不等式:

scala> tb.typecheck(tree1).tpe =:= tb.typecheck(tree2).tpe
res81: Boolean = false

我要求类型的表示:

scala> tb.typecheck(tree1).tpe
res82: tb.u.Type = st1 with st2{val x: X; val y: Y}

scala> tb.typecheck(tree2).tpe
res83: tb.u.Type = scala.AnyRef{val x: X; val y: Y}

现在这些类型成功统一了:

scala> implicitly[st1 with st2{val x: X; val y: Y} =:= scala.AnyRef{val x: X; val y: Y}]
res84: =:=[st1 with st2{val x: X; val y: Y},AnyRef{val x: X; val y: Y}] = <function1>

我可以以某种方式检查tree1tree2表示与上一个片段中类似类型的表达式吗?

编辑:最小定义

trait X 
trait Y 

type st1 = { val x: X } 
type st2 = { val y: Y } 
val s1: st1 = new { val x: X = new X {} } 
val s2: st2 = new { val y: Y = new Y {} } 

def foo(s1: st1, s2: st2): st1 with st2 { val x: X; val y: Y } = ??? 
val pure = new { val x: X = new X {}; val y: Y = new Y {}} 

val tree1 = reify { foo(s1, s2) }.tree 
val tree2 = reify { pure }.tree
4

1 回答 1

0

尝试

val typ1 = tb.typecheck(tree1).tpe
val typ2 = tb.typecheck(tree2).tpe

tb.typecheck(q"implicitly[$typ1 =:= $typ2]")

或者,同样的,

tb.typecheck(q"_root_.scala.Predef.implicitly[_root_.scala.Predef.=:=[$typ1, $typ2]]")

或者试试

tb.inferImplicitValue(tb.typecheck(tq"$typ1 =:= $typ2", mode = tb.TYPEmode).tpe, silent = false)

或者试试

implicit class TypeOps(tp1: Type) {
  def =::= (tp2: Type): Boolean = tp1 <:< tp2 && tp2 <:< tp1
}

typ1 =::= typ2 // true
于 2019-11-24T23:29:18.320 回答