2016-04-29 8 views

答えて

9

Clojure mapは怠け者であり、その結果を求めていないので、その内容は評価されず、swap!で機能が実行されません。 - これはどのようにswap!作品をテストするだけのサンプルコードであれば

(defn get-vector [] 
    (let [rs (atom [])] 
    (dorun (map (fn [x] (swap! rs conj x)) [1 2 3 4])) 
    @rs)) 

(get-vector) 
;; => [1 2 3 4] 

私が解決しようとしている問題を確認していない:それはあなたがdorunを使用して、その内容を実現することを強制すべき作業得るために

そのコードよりもOKです。それ以外の場合は、reduceのような別のソリューションを使用して、変更可能な参照を避けることもできます。

@Shlomiによって示唆されるように、副作用のためdoseqを使用することがより慣用のようになります。

(let [rs (atom [])] 
    (doseq [x [1 2 3 4]] 
    (swap! rs conj x)) 
    @rs) 
+5

'map'は副作用のための慣用句ではなく、[' doseq'](https://clojuredocs.org/clojure.core/doseq) – Shlomi

+0

があります。このようなシナリオでは 'doseq'を使う方が良いでしょう。私は答えを強化しましょう。 –

1

doseqは、より慣用的ですが、私はmapの構文を好むので、別のオプションは、maprunを作成することですこれを実現するためのシーケンスを強制的に:

(def maprun (comp dorun map)) 

(defn get-vector [] 
    (let [rs (atom [])] 
    (maprun (fn [x] (swap! rs conj x)) [1 2 3 4]) 
    @rs)) 

(get-vector) 

maprunは単なるシンタックスシュガーであるように、これは、技術的にPiotrekのと同じです。

+1

この関数は、名前が['run!'](http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/run!)で、すでにコアライブラリの一部であるため。 – glts

関連する問題