date: | 2012/11/08 |
---|
OR (||) とは、真偽値を2つとって、1つの真偽値を返すものです。 例えば、
True || False -- True になる
です。OR の返り値は以下の通りです。
True | False | |
---|---|---|
True | True | True |
False | True | False |
とある真偽値の無限リスト List があるとします。
[True, True, False, True, False, True, ....] -- ....以降は、何か複雑な列
リストのORによる右から左への折り畳み(注意: foldr1 (||) と言いたい) を
(True || (True || (False || (True || (False || (True || ....
さて、実際に次の式を評価した時に、無事に結果を得ることができるでしょうか?
(True || (True || (False || (True || (False || (True || ....
Answer: | できます |
---|
ちょっと (||) の定義を見てみましょう。
1 2 3 | (||) :: Bool -> Bool -> Bool
True || _ = True
False || x = x
|
遅延評価では、このような場合に2つ目の引数を評価しません。
つまり、先ほどの式では、
(True || "複雑なリスト" ....
という先頭の部分を評価した段階で結果が返ってくるので、無限リストに対しても評価を終えることができるのです。
Note
例えば、新しい関数 (|||) を次のように定義したとします。
(|||) :: Bool -> Bool -> Bool
True ||| True = True
True ||| False = True
False ||| True = True
Flase ||| False = False
遅延評価すごい。
Ruby でも遅延評価ができるようになると聞いてやってみた。 (参考: https://speakerdeck.com/nagachika/rubyist-enumeratorlazy)
p [true, false].cycle.lazy.any?
# => true
p [1, -1].cycle.lazy.any?{|n| n < 0}
# => true
#p [true, false].cycle.lazy.reduce{|res, item| res || item}
# => これは結果が返らない
スライドを見る限り割と便利なので、早く Ruby 2.0 が標準になってほしい、と(Ruby 書けるわけでもないけど)思いました。