为什么Scala无法按照文档进行工作?

时间:2014-01-24 19:14:28

标签: scala abstract-syntax-tree reification

2.10.3的Scala API文档说我可以“使用refiy生成表示给定Scala表达式的抽象语法树”。因此,我可以这样做:

scala> val uni = scala.reflect.runtime.universe 
uni: scala.reflect.api.JavaUniverse = scala.reflect.runtime.JavaUniverse@4e42766

scala> uni reify { 1 to 3 } 
res2: uni.Expr[scala.collection.immutable.Range.Inclusive] = Expr[scala.collection.immutable.Range.Inclusive](Predef.intWrapper(1).to(3))

在上面的例子中,我得到了我想要的东西:Predef.intWrapper(1).to(3))(一个方便的扩展表示要执行的操作)。

但是,当我试图重新启用1 + 3时,我并不代表我希望执行的操作。

scala> uni reify { 1 + 3 }
res5: uni.Expr[Int(4)] = Expr[Int(4)](4)

这是预期的行为吗? +是原始操作,因此没有具体化吗?

Scala文档显示了一个具体化的例子,暗示了一个更有用的表示形式:

reify{ 2 + 4 } // Apply( Select( Literal(Constant(2)), newTermName("$plus")), List( Literal(Constant(4)) ) )

如何检查1 + 3(如果存在)的正确扩展表示,以及如何检索任何表达式的详细表示(紧接在上面)?

编辑:我现在看到Scala文档中的表示形式是由showRaw生成的。但是,我仍然无法重现上面示例中2 + 4的原始表示形式。

1 个答案:

答案 0 :(得分:5)

见Eugene Burmako的this answer

  

宏连接到类型检查(在宏观参数的意义上   在宏扩展之前进行了类型检查),并进行了类型检查   常数

reify是使用宏实现的。

你应该像这样阻止持续折叠:

{
  val i = 1
  showRaw{ reify{i + 2}.tree }
}
// Apply(Select(Ident(newTermName("i")), newTermName("$plus")), List(Literal(Constant(2))))