3

Clojure For Comprehension の例での私の回答には、独自の出力を処理する関数があります。

(defn stream [seed]
  (defn helper [slow]
    (concat (map #(str (first slow) %) seed) (lazy-seq (helper (rest slow)))))
  (declare delayed)
  (let [slow (cons "" (lazy-seq delayed))]
    (def delayed (helper slow))
    delayed))

(take 25 (stream ["a" "b" "c"]))
("a" "b" "c" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc" "aaa" "aab" "aac" 
"aba" "abb" "abc" "aca" "acb" "acc" "baa" "bab" "bac" "bba")

delayedこれは、遅延シーケンス ( ) の 2 番目のエントリとして使用される前方参照 ( ) を作成することによって機能しslowます。そのシーケンスは遅延関数に渡され、その関数からの出力 ( の評価を必要としない遅延シーケンスの最初の部分delayed) を使用して の値が設定されますdelayed

このように「結び目を結ぶ」のです。しかし、これは Haskell ではよりエレガントに行われます (例: 「結び目を結ぶ」の説明</a>)。delayClojure にはとがあることを考えるとforce、上記を行うためのより良い方法があるかどうか疑問に思いましたか?

質問: 上記のコードで、(の、醜い、明示的な) 突然変異 (のdelayed) をどうにかして回避することはできますか? 明らかに(?) ミューテーションはまだ必要ですが、「怠惰な」構造で隠すことはできますか?

[昨夜、これを行う方法をまだ理解しようとしていたときに、同様のタイトルで質問がありました。上記のコードが機能する前に誰も返信しなかったので、削除しましたが、このアプローチにはあまり満足していないので、もう一度試しています.]

参照: Clojure の循環データ構造には ref のような構造が必要ですか? (人々が質問を複製していることにちょっとイライラします)。

4

1 に答える 1

2

一般的なケースの質問に答えられるかどうかはわかりませんが、この関数は特定のケースを解決するようです。

(defn stream
  [seed]
  (let [step (fn [prev] (for [p prev s seed] (str p s)))]
    (for [x (iterate step seed) y x] y)))

大きな(dorun (take ...)). したがって、この機能に問題がある可能性があります。

于 2012-07-19T20:47:36.083 に答える