Scala DSL和Block作为函数参数

时间:2013-12-30 15:21:32

标签: function scala dsl

如何在Scala实现DSL构造

def objeects(f: => Int):Int {
 println(f)
 // ??? evaluate every function, that f contain in the block. 
}          

manytimes {
 1+1
 2+1
 3+1
}                                              

结果我们需要为每个函数进行一次计算,因为我们将块传递给该方法。

9

2 个答案:

答案 0 :(得分:0)

你的块是一个功能:

{
 1+1 // calculate 2 and throw away
 2+1 // calculate 3 and throw away
 3+1 // return 4
}

这就是Scala语法的工作原理,您无法更改它。事实上,如果可以的话,在这种情况下你会发生什么?

manytimes {
  val x = 1
  val y = 2
  x + y
}

威尔

manytimes(1+1)(2+1)(3+1)

对你的目的是否足够好?

答案 1 :(得分:0)

经过几个小时的搜索,我发现了一些非常好的组件,这可以帮助我解决我的问题。

multifunc { 
            println(1)
            println(2) 
          }
// output
Expr[c.universe.Tree](func.tree)
scala.this.Predef.println(2) // <-- it my case its the second and last elem
class scala.reflect.internal.Trees$Apply // <-- we can apply it as usual
class scala.reflect.internal.Trees$Block
tree<<
class scala.reflect.internal.Trees$EmptyTree$
<empty>

宏观:     import scala.language.experimental.macros     import scala.reflect.macros._     def multifunc [A](func:=&gt; A)=宏_multifunc [A]

def _multifunc [A](c: BlackboxContext)(
func: c.Expr[A]
): c.Expr[Unit] = {
import c.universe._

val tree = func.tree match {
  case q"($i: $t) => $body" => q"""
      println($body)
      println($body.getClass)
      $body
    """
  case _ => q""
}


println(func.tree.children.last) // <-- accessor to AST children
println(func.tree.children.last.getClass)
println(func.tree.getClass)
println("tree<<")
println(tree.getClass)
println(tree)
c.Expr(tree)
}