Reputation: 7374
When writing some Clojure code I ran into the following problem.
I have three functions F1 F2 F3
Now I want to execute the three functions in sequence and thred the output from F1 to F2 and then use the conjoined results F1 AND F2 as input to F3 .
I have limited knowledge about monads but this struck me as exactly the type of problem the state monad is designed for?
What is the idiomatic way in Clojure for dealing with a situation like this?
Update: The functions are not returnng conjoined results. I need to conjoin the results after each function call.
Upvotes: 2
Views: 284
Reputation: 9886
(-> :value
f1
f2
f3)
This is using the thread macro, see also ->>
When I was looking for information and learning monads myself in clojure both Jim Duey's State monad and Konrad Hinsen's Monad tutorials helped a lot.
However, if you're looking for idiomatic, the Thread Macro above is the way to go, the results from f1 are thread into f2, and it's results into f3. Are you restricted in the design of the functions?
Finally, there's this SO question here with a link to state examples
Upvotes: 3
Reputation: 530
You don't need the state monad.
(def pipe [n]
(letfn [(F1 [x] (inc x))
(F2 [y] (dec y))
(F3 [z w] (/ z w))]
(let [r1 (F1 n)
r2 (-> n F1 F2)]
(F3 r1 r2)))
I'm not sure if this exactly what you're aiming for. Most of the problems the state monad solves do not exist in Clojure because we have let bindings. For r2 I used the thread first macro ->
it changes the order of execution so that you can do function application left to right instead of inside out.
Upvotes: -1