2016-10-23 5 views
2
キックのために

、私はmapの私の独自のバージョンを書くことにしましたが、最終的には正しくlazy-seqを使用する方法を学び、怠惰なマップを作るためにそれを使用する怠惰なシナリオで奇妙な振る舞いしかし、私がその怠惰な行動をmapに対してテストしたとき、私は何か違ったことに気づいた。私は標準map機能を使用する場合は要素が機能の間で交互に、一度に1つずつ処理され、カスタムマップ機能は

(defn print-map [description-str f coll mapping-f] 
    (mapping-f 
    (fn [x] 
     (do 
     (print (str description-str ":" x)) 
     (f x))) 
    coll)) 

(defn -main [] 
    (let [m map 
     coll (into '() (range 10 0 -1)) 
     coll2 (print-map "A" identity coll m) 
     coll3 (print-map "B" identity coll2 m)] 
    (println (doall coll3)))) 
Iは、要素が処理されるときに印刷ヘルパーマップ機能を使用してい

プリント:各番号は要素の残りのいずれかの関数によって見られる最初の前に、両方の機能で処理される方法

A:1 B:1 A:2 B:2 A:3 B:3 A:4 B:4 A:5 B:5 A:6 B:6 A:7 B:7 A:8 B:8 A:9 B:9 A:10 B:10 (1 2 3 4 5 6 7 8 9 10) 

注意。

しかし、私は少し、my-map-mainに処理順序の変更をmを変更:

A:1 A:2 B:1 A:3 B:2 A:4 B:3 A:5 B:4 A:6 B:5 A:7 B:6 A:8 B:7 A:9 B:8 A:10 B:9 B:10 (1 2 3 4 5 6 7 8 9 10) 

今最初の関数の開始が二回実行され、第二の機能は、最終的に2回連続で実行され、結果として、マッピングはもはや「同期していない」。

my-mapで何が問題になるのですか?

答えて

4

my-mapで破壊すると、遅い順番でnextが呼び出されます。

あなたは破壊しないことで、これを避けることができます。

(defn my-map [f [x :as xs]] 
    #_(next xs) ;; uncomment to observere similar "broken" behaviour 
    (lazy-seq 
    (if x 
     (cons (f x) (my-map f (rest xs))) 
     (rest xs)))) 

;; You can find out what destructing does with this call: 
(destructure '[[x & r :as xs] numbers]) 

next is not as lazy as restを。

+0

Ohh。ありがとうございました。 – Carcigenicate

関連する問題