2011-07-21 6 views
4

私はDSLを作成しようとしていますが、問題が発生しています。Scala - DSLのapplyメソッドのカッコを省略します。

scala> \ a b 
Lam(Var(a),Var(b)) 

がカッコ落ちのルール上に読んで、私は私は1つのパラメータそれぞれを取るチェーン機能に必要であることを参照してください。私はこれを行うことができるようにしたい

case class Var(name: String) 
case class Lam(v: Var, t: Var) 
val (a, b) = (Var("a"), Var("b")) 

:私はこれらの定義を持っています私は、各applyは一引数を取るので、これは仕事と期待していた

class LamBuilderB(v: Var) { 
    def apply(t: Var) = Lam(v, t) 
} 

class LamBuilderA { 
    def apply(v: Var) = new LamBuilderB(v) 
} 

val \ = new LamBuilderA 

:ので、私は建設を行う「ビルダー」一連のクラスを作成しました。しかし、それは括弧を落とすように見えるしていませんが、それはメソッド名として引数を処理したいので、applyための法的です:

scala> \(a)(b) 
res95: Lam = Lam(Var(a),Var(b)) 

scala> \ a b 
error: value a is not a member of LamBuilderA 
    \ a b 
    ^

任意のアイデアをどのように私は括弧なしでDSLの構文を取得できますか?

ボーナス質問:私はこれが

scala> \a.b 
Lam(Var(a),Var(b)) 
+1

私は確かにあなたが '\ ab'を手に入れられないことを願っています! '.'をオーバーロードすることは、私が埋め込まれたDSLのために良いアイデアと呼ぶものではありません。 –

答えて

6

を?:取得できますが、4つの単項演算子(~!+-)のいずれかを使用してかなり近づくことができます。

trait Expr { 
    def &(other: Expr) = Lam(this, other) 
    def unary_~ = this 
} 

case class Var(name: String) extends Expr 
case class Lam(a: Expr, b: Expr) extends Expr 

scala> ~ Var("a") & Var("b") 
res0: Lam = Lam(Var(a),Var(b)) 

scala> ~ Var("a") & Var("b") & Var("c") 
res1: Lam = Lam(Lam(Var(a),Var(b)),Var(c)) 
+0

この面白い答えをありがとう。私は構文として '\(a、b)'を使わなければならないと思いますが、単項演算子を利用するのは良い考えです。 – dhg

関連する問題