2012-04-20 12 views
3

スカラに論理的な意味を実装する可能性があるのだろうかと思っていました。 例えば:に翻訳スカラに暗黙の論理演算子を実装する

a implies b 

!a || b 

abBooleanに評価するいくつかの式です。

私は当初、以下で始めたが、それは関係なく、aの値をabの両方を評価しますので、それは

implicit def extendedBoolean(a : Boolean) = new { 
    def implies(b : Boolean) = { 
     !a || b 
    } 
    } 

間違ったアプローチです。正しい解決策は、aが真の場合にのみbと評価されます。

答えて

5

あなたは、私は次のように十分であると信じて、コール・バイ・名パラメータを使用します:

implicit def extendedBoolean(a : Boolean) = new { 
    def implies(b : => Boolean) = { 
     !a || b 
    } 
    } 

は説明:

あなたはbのためにいくつかの値を渡す必要がありますが、あなたはそれをしたくありません評価された式。 Scalaは自動的に式を引数をとらない式に変換して式に評価します。 implies演算子は、必要であれば、その関数がゼロ(ゼロ)であることを評価します。

コンパイラは、提供した型シグニチャ=> Booleanのためにこの変換を実行できることを認識しています。このpostはより詳細に説明されていますが、そのタイトルだけでは、何が起こっているのかの非常に良い要約の説明です:"Automatic Type-Dependent Closure Construction"

Scalaのこの機能は、他の言語のマクロを使って簡単に書くことができるように、制御構造を書くことができます。条件付きのパラメータと本体用のパラメータの2つのパラメータを使用してwhileループを簡単に再実装する方法を確認します。

object TargetTest2 extends Application { 
    //type signature not too terribly mysterious 
    def whileLoop(cond: => Boolean)(body: => Unit): Unit = 
    if (cond) { 
     body 
     whileLoop(cond)(body) 
    } 

    //about as easy to use as a plain-old while() loop 
    var i = 10 
    whileLoop (i > 0) { 
    println(i) 
    i -= 1 
    } 
} 
+2

スカラでは、* nullary関数*は* call-by-name引数*と呼ばれています。 – ziggystar

+1

真。私がリンクしているScalaのWebサイトのページでは、Scalaでは式をnullary関数に自動的に変換することで、「名前による評価」が実装されています。Skalaが言語機能を実装するのは、名前による呼び出しを使用する方法に留意するよりも、面白くて教育的だと思います。 – ellisbben

+0

は、これが名前による呼び出しの場合であることを強調するために編集されています – ellisbben

4

bを評価する必要がある機能にしたいと考えています。そうすれば、実際にアクセスされた場合にのみ評価されます。

このタイプは=> Booleanに変更されています。これは何も入力せずにBooleanと評価されるものです。

implicit def extendedBoolean(a: Boolean) = new { 
    def implies(b: => Boolean) = { 
    !a || b 
    } 
} 

は、ここでそれを使用する方法は次のとおりです。atruebであること

scala> true implies { println("evaluated"); true } 
evaluated 
res0: Boolean = true 

scala> false implies { println("evaluated"); true } 
res1: Boolean = true 

通知は(印刷 "を評価")に評価されます。しかし、afalseの場合、評価されません(何も印刷されません)。