<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>Thank you so much! That was very enlightening!<br>
</p>
<br>
<div class="moz-cite-prefix">Am 20.05.16 um 21:09 schrieb Silent
Leaf:<br>
</div>
<blockquote
cite="mid:CAGFccjNHk0JR4d9Yv1hWbT-+sQDNdukgYhf+JMPC4JBOMzDh3g@mail.gmail.com"
type="cite">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 moz-do-not-send="true"
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 moz-do-not-send="true"
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 moz-do-not-send="true"
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 moz-do-not-send="true"
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 moz-do-not-send="true"
href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
> <a moz-do-not-send="true"
href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
Beginners mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Beginners@haskell.org">Beginners@haskell.org</a>
<a class="moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a>
</pre>
</blockquote>
<br>
</body>
</html>