2016-05-20 15 views
2

最終的に真実の価値を持つリストをチェックするための関数/マクロが必要です。評価が怠け者になることを願っています。ここでは、遅延評価なしで私の説明の実装です:ここではClojureのリストでは、慣習的で怠け者です。

(defn eventual [cols] 
    (or (first cols) (if-let [rs (rest cols)] 
        (eventual rs)) 
        false)) 

は説明するための簡単な例です:

(if (eventual [false (+ 1 2) (* 10000 10000)]) 
    true 
    false) 

私は怠惰な評価の意味合いがなければならないと感じています。多分、私はちょうど現時点では盲目になっています。助けてください。おかげ

答えて

2

シーケンスはsome機能を有する少なくとも一つのtruthyの要素が含まれている場合は、確認することができます。

(some identity col) 

あなたはそれを、それが最初truthy要素とウォンまでその内容を評価しますcolとして怠惰なシーケンスを渡す場合

(let [col (take 
      10 
      (iterate 
       #(do (println "Generating new value from " %) (inc %)) 
       0))] 
    (some #(> % 5) col)) 

を生成します:

Generating new value from 0 
Generating new value from 1 
Generating new value from 2 
Generating new value from 3 
Generating new value from 4 
Generating new value from 5 
true 
「がtは休息を実現します

ご覧のとおり、値6..9はまったく生成されません。

また、someに渡されたcolは、あなたを混乱させる可能性があるため、実際には怠け者であり、まだ実現していないことを再確認してください。

+0

本当の慣用句を手に入れてくれてありがとう! –

2

eventualの機能は、できるだけ怠惰です。それは熱心に最初の真実の項目を探してから停止します。しかし、それは問題があります:

  • 空のコレクションで終了しません。 (rest())(), です。これは真実です。 restの代わりにnextを使用してください。 (next())nil, であり、これは偽である。
  • 本当に再帰的です。それは十分に長く 検索でスタックを吹くでしょう。試してください(eventual (repeat false))。再帰は テール再帰であるため、代わりにrecurを使用してこれを修正できます。
  • コレクションを使い果たしたときにはnilでなくfalse,ではありません。最終的にはfalseをドロップしてください。

私たちは、私がcolsが空の場合、何が起こるかについて少しムカムカしてい

(defn eventual [cols] 
    (or (first cols) (if-let [rs (next cols)] 
        (recur rs)))) 

で終わります。 the source for someに基づいてコードが明確である:

(defn eventual [coll] 
    (when (seq coll) 
     (or (first coll) (recur next coll)))) 

しかし(some identity col)を使用して、Piotrekが示唆するように、おそらく最高です。

+0

私の実装の問題を見つけて、それを修正してくれてありがとう。 –

関連する問題