> ...and report your findings here or blog somewhere if you don't mind > :) I've been reading a lot about monads lately and can't get my head > around it yet so any help appreciated (I'm coming from Java and > Clojure is my first real functional language - that's why it causes > headaches, I believe). >
I have no blog so I will try an explanation here. I think monad are quite difficult to grasp, so the more different explanations you read, the better. Monads are made to represent computations in an abstract way. Sometimes the basic computation laws are not those you want and then you want to introduce other computation laws. Monad is one way to do so (among other like applicative functors or Kieisli arrows) Monad corresponds to the computations that are best described as an imperative program. So a monad is a type transformer: M<A> for all A , in Java words. Something of type M<A> is a computation in the world of computation M that returns values of type A. (M for example can be IO: the computations that do input/outputs to find their results, State: the computations that use a and update an internal state List: more surprisingly, the non-deterministic computations: each computation yeilds a list of possible results) There are a few operators you need for a monad: - return : A -> M<A> . It says that any computation model must be able to handle the lack of computation. "Do nothing and return this value" - bind : M<A> -> (A -> M<B>) -> M<B> "If I give you a computation that gives back values in A and for each values in A I tell you how to compute a value in B, then you can compute a value in B. " That's a strong assumption, because it allows to use the whole power of Clojure to construct a computation from the result of the first computation. Some model of computations are more restrictive than monad on that. >From this two operators you can define two others: - map : (A -> B) -> M<A> -> M<B> "If I give you a function from A to B, then you can transform a computation that returns value in A in computation that returns values in B." (map f compA = (bind compA (fn [x] (return (f x))))) - join : M<M<A>> -> M<A> "I can run a subprogram" This is again something quite specific to monad as computation devices. (Bind can be constructed from join and map) They are dynamic programs that can compute a program and run it. join compMA = (bind compMA identity) bind compA f = (join (map f compA)) All these operators must respect some laws, that are quite natural. Like returning a value and starting a computation is the same as starting a computation directly from the value: - (bind (return a) f) = (f a) .... To work out an example, the state monad is a computation that can use and modify a state, so: M<A> = S -> [S, A] . I need a state and return a new state and a value A. return a = (fn [s] -> [s a]) bind compA f = (fn [s1] -> ; we give the state to the first comutation (let [[s2 a] (compA s1) ; we compute the next computation compB (f a)] ; we give the state to the second computation (compB s2))) Hope that helps. Nicolas. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en