今日、結び目と循環データ構造を結ぶことへの言及を見てきました。私はいくつかの回答を読んでいますが、解決策には、参照を使用してリストの先頭を指すことが含まれているようです。1 つの特定のSO の質問で Haskell の例が示されましたが、その例が ref に相当する Haskell を使用しているかどうかを知るのに十分なほど Haskell を知りません。
ref または同様の構造を使用せずに Clojure データ構造を循環させる方法はありますか?
ありがとう。
今日、結び目と循環データ構造を結ぶことへの言及を見てきました。私はいくつかの回答を読んでいますが、解決策には、参照を使用してリストの先頭を指すことが含まれているようです。1 つの特定のSO の質問で Haskell の例が示されましたが、その例が ref に相当する Haskell を使用しているかどうかを知るのに十分なほど Haskell を知りません。
ref または同様の構造を使用せずに Clojure データ構造を循環させる方法はありますか?
ありがとう。
Haskell の例をそのまま Clojure に翻訳しました。
user> (def alternates
(letfn [(x [] (lazy-seq (cons 0 (y))))
(y [] (lazy-seq (cons 1 (x))))]
(x)))
#'user/alternates
user> (take 7 alternates)
(0 1 0 1 0 1 0)
期待どおりに動作します。ただし、次cycle
を使用した相互再帰関数よりも関数を好みletfn
ます。
user> (take 7 (cycle [0 1]))
(0 1 0 1 0 1 0)
標準の Clojure の不変データ構造と標準の Clojure 関数を使用して循環参照を作成することは不可能です。これは、2 番目に作成されたオブジェクトは、最初に作成された (不変の) オブジェクトに決して追加できないためです。
ただし、少しトリックを使用する場合は、循環データ構造を作成する方法がいくつかあります。
ただし、一般に、循環データ構造は Clojure では避けるのが最善です。
私は以前にこれを使用しました:
;; circular list operations
(defn rotate
([cl] (conj (into [](rest cl)) (first cl)))
([cl n] (nth (iterate rotate cl) (mod n (count cl)))))
出力はベクトルですが、入力は任意のシーケンスにすることができます。