1. ホーム
  2. clojure

[解決済み] ClojureのTransducersを簡単に説明できる人はいますか?

2022-10-09 03:36:33

質問

私はこのことについて読んでみましたが、まだそれらの価値やそれらが何を置き換えるのかを理解していません。そして、それらは私のコードをより短く、より理解しやすくするか、または何ですか?

更新

多くの人が回答を投稿していますが、私のような馬鹿でも理解できる非常に単純なものについて、トランスデューサを使用した場合と使用しない場合の例を見ることができたらいいと思います。もちろん、トランスデューサーがある種の高度な理解を必要とする場合は別ですが、その場合、私はそれを理解することはできないでしょう :(

どのように解決するのですか?

トランスデューサーは、基礎となるシーケンスが何であるか(どのようにそれを行うか)についての知識なしに、データのシーケンスで何を行うかのレシピです。それはどんなシーケンスでも、非同期チャンネルでも、あるいは観測可能なものでもよいでしょう。

トランスデューサは構成可能で多相です。

利点は、新しいデータソースが追加されるたびに、すべての標準的なコンビネータを実装する必要がないことです。何度も何度もです。その結果、ユーザーとして、異なるデータソースでそれらのレシピを再利用することができます。

Clojureのバージョン1.7以前は、データフロークエリを書くために3つの方法がありました。

  1. ネストされた呼び出し

    (reduce + (filter odd? (map #(+ 2 %) (range 0 10))))
    
    
  2. 機能構成

    (def xform
      (comp
        (partial filter odd?)
        (partial map #(+ 2 %))))
    (reduce + (xform (range 0 10)))
    
    
  3. スレッドマクロ

    (defn xform [xs]
      (->> xs
           (map #(+ 2 %))
           (filter odd?)))
    (reduce + (xform (range 0 10)))
    
    

トランスデューサーを使うと、次のように書きます。

(def xform
  (comp
    (map #(+ 2 %))
    (filter odd?)))
(transduce xform + (range 0 10))

これらはすべて同じことをします。違いは、直接トランスデューサを呼び出すことはなく、別の関数に渡すということです。トランスデューサーは何をすべきかを知っており、トランスデューサーを取得した関数はどのようにするかを知っています。コンビネータの順序は、スレッドマクロで書いたようなものです(自然な順序)。これで xform をチャネルで再利用できるようになりました。

(chan 1 xform)