2013-07-06 22 views
6

Uruchomiłem w kilku sytuacjach, w których chcę wykonać łańcuch operacji na obiekcie z opcjonalnymi funkcjami. "->" działa świetnie na sekwencje poleceń na tym samym obiekcie (np. (c (b (a x))) staje się (-> x a b c)), chyba że niektóre operacje są opcjonalne. Na przykład, załóżmy, że chciałem zrobić:Operator clojure -> (strzałka) i operacje opcjonalne

(c 
    (if (> (a x) 2) 
    (b (a x)) 
    (a x) 
    ) 
) 

Czy jest jakiś sposób, aby to zrobić w jaśniejszy sposób za pomocą operacji jak „->”?

Odpowiedz

10

Można to zrobić z cond->, nowo wprowadzony w Clojure 1.5:

(cond-> x 
    true  a 
    (> (a x) 2) b 
    true  c) 

Albo lepiej,

(-> x 
    a 
    (cond-> (> (a x) 2) b) 
    c) 

znaczeniu, „Take x, przewlecz przez a, podejmują wynik i przeprowadź przez , jeśli nie zostanie zmieniony, w końcu weź to, co masz i przeprowadź przez ".

Innymi słowy cond-> jest jak -> wyjątkiem zamiast pojedynczych postaciach do wątku swój wyraz w trwa testowa + tworzące pary, w którym forma jest pomijany, jeżeli test jest falsey i używane do gwintowania Jeśli test jest truthy:

(cond-> x 
    test-1 form-1 
    test-2 form-2) 

;; if test-1 is truthy and test-2 is falsey, output is as if from 
(-> x test-1) 

;; if it's the other way around, output is as if from 
(-> x test-2) 

;; if both tests are truthy: 
(-> x test-1 test-2) 

;; if both tests are falsey: 
x 
+3

Nawiasem mówiąc, 'cond->' jest moim osobistym mistrzem w najbardziej nieczytelnym konkursie na doctring. –

+1

Kolejne przeformułowanie: "bierze x i klauzule, interpretuje zdania jako pary testu i wyraż, a następnie wątki x przez te wyrażenia, dla których odpowiednie testy są zgodne z prawdą." –

+0

Pallet [thread-expr] (https://github.com/pallet/thread-expr) ma więcej podobnych programów fns. – noahlz

Powiązane problemy