5

今日、結び目と循環データ構造を結ぶことへの言及を見てきました。私はいくつかの回答を読んでいますが、解決策には、参照を使用してリストの先頭を指すことが含まれているようです。1 つの特定のSO の質問で Haskell の例が示されましたが、その例が ref に相当する Haskell を使用しているかどうかを知るのに十分なほど Haskell を知りません。

ref または同様の構造を使用せずに Clojure データ構造を循環させる方法はありますか?

ありがとう。

4

3 に答える 3

6

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)
于 2012-07-19T21:06:57.750 に答える
6

標準の Clojure の不変データ構造と標準の Clojure 関数を使用して循環参照を作成することは不可能です。これは、2 番目に作成されたオブジェクトは、最初に作成された (不変の) オブジェクトに決して追加できないためです。

ただし、少しトリックを使用する場合は、循環データ構造を作成する方法がいくつかあります。

  • 参照、アトムなど
  • 変更可能な定義型
  • Java オブジェクト
  • リフレクションの策略
  • 遅延シーケンス

ただし、一般に、循環データ構造は Clojure では避けるのが最善です。

于 2012-07-20T04:12:24.280 に答える
3

私は以前にこれを使用しました:

;; circular list operations
(defn rotate
   ([cl] (conj (into [](rest cl)) (first cl)))
   ([cl n] (nth (iterate rotate cl) (mod n (count cl)))))

出力はベクトルですが、入力は任意のシーケンスにすることができます。

于 2012-07-19T20:05:58.647 に答える