yes, this definition of bind2 looks kinda "frightening". if fact it's simpler than it looks: (.::) merely takes two functions, then the three next parameters applied to the result of this special composition, will be applied to the second parameter, before the result be given as input for the first parameter.<br><br>it must be compared with (.), which only allows the second function to get one single parameter, before the result of this application becomes the first parameter of the first function of the composition, after which any supplementary parameter applied to the whole will go to the left function:<br>> (left . right) a b c d e = left (right a) b c d e<br>By comparison:<br>> (left .:: right) a b c d e = left (right a b c) d e<br> <br>in the first equation above, defining (.), let's say `right` has type a -> b -> c -> d. then `left` will get as first parameter, a partial function, aka (right a :: b -> c -> d). but, in the second equation, `right` gets all of its three parameters (a, b and c), returning a value of type `d`, before `left` gets said result-value as its own first parameter, and then possibly get other parameters of its own (here, d and e).<br><br>thus with bind2:<br>bind2 f ma mb = (join .:: liftM2) f ma mb = join (liftM2 f ma mb)<br><br>Now, in my opinion, the point-free style definition of (.::), aka composition of (.) with itself, three time, is way overkill (better use a lambda to clarify the purpose), but maybe is it better in terms of performance or whatever. it's certainly shorter, and when you know what it entails, it's simple, but it can easily frighten anyone else.<br><br>if one wants to understand this (subjectively overkill) point-free definition,<br>(.::) = (.) . (.) .(.)<br>better do the opposite action that leads to point free style, aka, better name and reveal variables. To make it more readable, i'll define first:<br>dot = (.)<br>f .:: g = (dot . dot . dot) f g<br>        = (dot . dot) (dot f) g<br>        = (dot . dot) (f .) g<br>        = dot (dot (f .)) g<br>        = dot ((f .).) g<br>        = ((f . ) .) . g<br>this expansion (or whatever you call it), solely uses the basic rule (a . b) c = a (b c), or, with "pollution" around, (w . a . b) c d = (w . a) (b c) d = w (a (b c)) d.<br>in the case of b = dot = (.), and c = f, you get (dot f) = (f .), aka, partially applied composition of f with "something" (the implicit parameter).<br><br>now, this weird<br>((f .) .) . g = f .:: g<br>is as we said, directly equivalent to<br>\f g a b c -> f (g a b c)<br>indeed:<br>>   f .:: g<br>> = (((f .) .) . g) a b c -- structure equivalent to (x.g) a b c<br>> = ((f .) .) (g a) b c   -- to (w .) (g a) b c   [with x = (w.) and w = (f .)]<br>> = ((f .) . (g a)) b c   -- to (w . (g a)) b c = (w . v) a b<br>> = (f .) ((g a) b) c     -- to (f.) (v b) c = (f.) (g a b) c -- as v = g a<br>> = (f  . (g a b)) c      -- to (f . k) c   [with k = (g a b)]<br>> = f ((g a b) c) = f (g a b c)  -- to f (k c)<br>which is what we thought (.::) was.<br>simply put, every dot in<br>> (((f .) .)  .  g)  a  b  c<br>will allow, first, with the dot to the right, that g, as right side of a function composition, take the first argument that follows (here a), becoming a binary partial app (g a);<br>> ((f .) . (g a))  b  c -- first dot was used<br>then, this binary partial app (g a) being now the right side of another composition (second, aka middle dot), will get a new argument of its own (b), making it an unary partial app (g a b)<br>> (f . (g a b))  c -- second dot was used<br>and the last dot the the extreme left, at last, allows (g a b) to take its last argument before finally the result be inputed to the function f:<br>> f (g a b c)<br><br>I hope it clarifies everything for anyone interested and that didn't know it already, of course.<br><br><br><br>Le vendredi 20 mai 2016, Tilmann <<a href="mailto:t_gass@gmx.de">t_gass@gmx.de</a>> a écrit :<br>> Thank you for the references. I like the term 'bind2'. I had a look at Prelude.Generalized. Wow!<br>><br>> bind2 = join .:: liftM2;<br>> (.::) = (.) . (.) . (.)<br>><br>> Am 20.05.16 um 04:50 schrieb Silent Leaf:<br>><br>> The interesting bit is, the following function > \φ ma mb -> join (pure φ <*> ma <*> mb) which i like to write as follows using ((&) = flip ($)) [infixl 1] > \φ ma mb -> pure φ <*> ma <*> mb & join (but it's just personal taste) is very similar to (=<<), aka (flip (>>=)) except the first argument (here φ) has type (a -> b -> m c) instead of (a -> m b), and of course the lambda above takes an added argument too (mb). Some could call it "bind2" (even if it's the flipped version of (>>=) that is being generalized), and well, some do. For those interested, there are several options are available to import it (along possibly with some of its siblings), from several libraries. (List possibly non exhaustive.) <a href="http://hackage.haskell.org/package/prelude-generalize-0.4/docs/Prelude-Generalize.html#v:bind2">http://hackage.haskell.org/package/prelude-generalize-0.4/docs/Prelude-Generalize.html#v:bind2</a> <a href="http://hackage.haskell.org/package/SimpleH-1.2/docs/Algebra-Monad.html#v:bind2">http://hackage.haskell.org/package/SimpleH-1.2/docs/Algebra-Monad.html#v:bind2</a> <a href="http://hackage.haskell.org/package/definitive-base-2.3/docs/Algebra-Monad-Base.html#v:bind2">http://hackage.haskell.org/package/definitive-base-2.3/docs/Algebra-Monad-Base.html#v:bind2</a> your problem become btw then: > doIt = bind2 update a b<br>><br>> _______________________________________________<br>> Beginners mailing list<br>> <a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>>