Sto cercando di fare un trasduttore condizionale in Clojure come segue:Implementazione Clojure condizionale/branching trasduttore
(defn if-xf
"Takes a predicate and two transducers.
Returns a new transducer that routes the input to one of the transducers
depending on the result of the predicate."
[pred a b]
(fn [rf]
(let [arf (a rf)
brf (b rf)]
(fn
([] (rf))
([result]
(rf result))
([result input]
(if (pred input)
(arf result input)
(brf result input)))))))
E 'molto utile in quanto permette di fare cose come questa:
;; multiply odd numbers by 100, square the evens.
(= [0 100 4 300 16 500 36 700 64 900]
(sequence
(if-xf odd? (map #(* % 100)) (map (fn [x] (* x x))))
(range 10)))
Tuttavia, questo trasduttore condizionale non funziona molto bene con i trasduttori che eseguono la pulizia nel loro ramo 1-arity:
;; negs are multiplied by 100, non-negs are partitioned by 2
;; BUT! where did 6 go?
;; expected: [-600 -500 -400 -300 -200 -100 [0 1] [2 3] [4 5] [6]]
;;
(= [-600 -500 -400 -300 -200 -100 [0 1] [2 3] [4 5]]
(sequence
(if-xf neg? (map #(* % 100)) (partition-all 2))
(range -6 7)))
È possibile modificare la definizione di if-xf
per gestire il caso dei trasduttori con la pulizia?
sto cercando questo, ma con un comportamento strano:
(defn if-xf
"Takes a predicate and two transducers.
Returns a new transducer that routes the input to one of the transducers
depending on the result of the predicate."
[pred a b]
(fn [rf]
(let [arf (a rf)
brf (b rf)]
(fn
([] (rf))
([result]
(arf result) ;; new!
(brf result) ;; new!
(rf result))
([result input]
(if (pred input)
(arf result input)
(brf result input)))))))
In particolare, il lavaggio avviene alla fine:
;; the [0] at the end should appear just before the 100.
(= [[-6 -5] [-4 -3] [-2 -1] 100 200 300 400 500 600 [0]]
(sequence
(if-xf pos? (map #(* % 100)) (partition-all 2))
(range -6 7)))
C'è un modo per rendere questa ramificazione/trasduttore condizionale senza memorizzando l'intera sequenza di input nello stato locale all'interno di questo trasduttore (cioè eseguendo tutta l'elaborazione nel ramo 1-arity al momento della pulizia)?
'(sequenza (se-xf pos? (Mappa # (*% 100)) (partizione-tutto 2)) [-1 1 0])' dà '([-1] 100)' nell'esempio, questo potrebbe non essere ciò che l'OP vuole – Davyzhu
Hai ragione. Devo rimuovere il 'vresets' e sta funzionando. Ma ora non capisco più perché non funzioni. :( – ClojureMostly
Perché 'arf' e' brf' devono essere volatili - non sembrano cambiare? Penso che con la restrizione che non possiamo bufferizzare, questo è probabilmente il migliore possibile. Sfortunatamente questa soluzione non lo fa t abbastanza lavoro in casi patologici, (ad esempio se uno dei trasduttori argomento buffer tutto e fa tutto il lavoro nel passaggio di completamento 1-arg). Sarebbe super cool se ci fosse un degrado aggraziato, dove se nessuno dei buffer di input xducer, quindi il 'if' non bufferizzerebbe, e altrimenti buffererà nella misura necessaria.I trasduttori non sono ancora magici, comunque. – dsg