なぜClojureのコードのこのビット:Clojureは常に、マップ機能
user=> (map (constantly (println "Loop it.")) (range 0 3))
収量この出力:
Loop it.
(nil nil nil)
が、私はそれが側として「ループそれを」三回を印刷するように期待関数を3回評価する効果。
なぜClojureのコードのこのビット:Clojureは常に、マップ機能
user=> (map (constantly (println "Loop it.")) (range 0 3))
収量この出力:
Loop it.
(nil nil nil)
が、私はそれが側として「ループそれを」三回を印刷するように期待関数を3回評価する効果。
constantly
引数を何度も評価しません。これは関数であり、マクロではないため、引数はconstantly
が実行される前に一度だけ評価されます。すべてconstantly
は、(評価された)引数をとり、呼び出されるたびに(指定された値を返す関数を返します)(constantly
が実行される前に引数が評価されているため、何も再評価しません)。
範囲内のすべての要素に対して(println "Loop it")
を呼び出す場合は、constantly
ではなく、マップする関数として渡す必要があります。実際には評価された式ではなく関数として渡す必要があることに注意してください。
repeatedlyとラムダ式で、あなたの意図に近い行動を得ることができます。例えば
:
(repeatedly 3 #(println "Loop it"))
あなたはREPLにいる場合を除き、これはdorun
または同様に囲まれる必要があります。 repeatedly
は遅延です。
sepp2kが正しく指摘したように、constantly
は関数なので、その引数は1回だけ評価されます。
あなたはここで何をしているかを達成するための慣用的な方法は、doseq
を使用することです:
(doseq [i (range 0 3)]
(println "Loop it."))
または代わりdotimes
(あなたが実際に使用していないとして、この特定のケースでは、もう少し簡潔かつ効率的ですrange
によって生成シーケンス):これらのソリューションの
(dotimes [i 3]
(println "Loop it."))
どちらも、あなただけの副作用のためにいくつかのコードを実行している場合、あなたが望むものはおそらくである、非怠惰です。
ソースを参照してください。これは勝者のように見えます。 – Mike
私が必要としない引数を明示的に渡すのを避けるために絶えず使用しようとしていました。しかし、これで解決します。 – Mike
副作用だけが必要な場合は、 'doseq'または' dotimes'を使うべきです。 'map'は怠惰なので、' doall'や 'dorun'で強制しない限り、望む結果を得ることはできません。 –