サーチ…


前書き

トランスデューサは、コンテキストとは独立してデータを処理するための構成可能なコンポーネントです。したがって、入力ソースや出力シンクを知らなくても、コレクション、ストリーム、チャンネルなどを処理することができます。

Clojureコアライブラリは1.7で拡張され、map、filter、takeなどのシーケンス関数はシーケンスなしで呼び出されるとトランスデューサを返すようになりました。トランスデューサは特定のコントラクトを持つ関数であるため、通常のcomp関数を使用して合成することができます。

備考

トランスデューサは、怠惰が消費されるときに制御することを可能にします。たとえばinto予想されるように熱心であるが、 sequenceレイジー変換器を介して配列を消費します。ただし、遅延保証は異なります。最初に要素を生成するのに十分なソースが消費されます。

(take 0 (sequence (map #(do (prn '-> %) %)) (range 5)))
;; -> 0
;; => ()

リストが空であるかどうかを判断する:

(take 0 (sequence (comp (map #(do (prn '-> %) %)) (remove number?)) (range 5)))
;; -> 0
;; -> 1
;; -> 2
;; -> 3
;; -> 4
;; => ()

これは通常の遅延的な動作とは異なります。

(take 0 (map #(do (prn '-> %) %) (range 5)))
;; => ()

小さなトランスデューサをベクトルに適用

(let [xf (comp
           (map inc)
           (filter even?))]
  (transduce xf + [1 2 3 4 5 6 7 8 9 10]))
;; => 30

この例では、ローカルに割り当てられたトランスデューサ作成xfして使用してtransduceいくつかのデータに適用します。トランスデューサはそれぞれの入力に1を加え、偶数だけを返します。

transducereduceようなもので、提供された+関数を使用して入力コレクションを単一の値に折りたたみます。

これはスレッド最後のマクロのように読み込まれますが、入力データは計算から分離されます。

(->> [1 2 3 4 5 6 7 8 9 10]
     (map inc)
     (filter even?)
     (reduce +))
;; => 30

トランスデューサの適用

(def xf (filter keyword?))

コレクションに適用し、シーケンスを返します。

(sequence xf [:a 1 2 :b :c]) ;; => (:a :b :c)

コレクションに適用し、結果のコレクションを別の関数で減らします。

(transduce xf str [:a 1 2 :b :c]) ;; => ":a:b:c"

コレクションに適用し、結果を別のコレクションにconjする:

(into [] xf [:a 1 2 :b :c]) ;; => [:a :b :c]

トランスデューサを使用してメッセージをフィルタリングするコア非同期チャネルを作成します。

(require '[clojure.core.async :refer [chan >!! <!! poll!]])
(doseq [e [:a 1 2 :b :c]] (>!! ch e))
(<!! ch) ;; => :a
(<!! ch) ;; => :b
(<!! ch) ;; => :c
(poll! ch) ;;=> nil

トランスデューサの作成/使用

したがって、Clojureのマップとフィルタで最もよく使用される関数は、コレクションで呼び出されなければトランスデューサ(合成可能なアルゴリズム変換)を返すように変更されています。つまり、

(map inc)はトランスデューサを返します(filter odd?)そうではありませ(filter odd?)

利点:compは関数を1つの関数にまとめることができます。これはコレクションを1回だけトラバースすることを意味します。一部のシナリオで実行時間を50%以上節約します。

定義:

(def composed-fn (comp (map inc) (filter odd?)))

使用法:

;; So instead of doing this:
(->> [1 8 3 10 5]
     (map inc)
    (filter odd?))
;; Output [9 11]

;; We do this: 
(into [] composed-fn [1 8 3 10 5])
;; Output: [9 11]


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow