[Haskell-beginners] Code golf

Tilmann t_gass at gmx.de
Sat May 21 14:03:50 UTC 2016


Thank you so much! That was very enlightening!


Am 20.05.16 um 21:09 schrieb Silent Leaf:
> 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.
>
> 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:
> > (left . right) a b c d e = left (right a) b c d e
> By comparison:
> > (left .:: right) a b c d e = left (right a b c) d e
>
> 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).
>
> thus with bind2:
> bind2 f ma mb = (join .:: liftM2) f ma mb = join (liftM2 f ma mb)
>
> 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.
>
> if one wants to understand this (subjectively overkill) point-free 
> definition,
> (.::) = (.) . (.) .(.)
> 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:
> dot = (.)
> f .:: g = (dot . dot . dot) f g
>        = (dot . dot) (dot f) g
>        = (dot . dot) (f .) g
>        = dot (dot (f .)) g
>        = dot ((f .).) g
>        = ((f . ) .) . g
> 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.
> 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).
>
> now, this weird
> ((f .) .) . g = f .:: g
> is as we said, directly equivalent to
> \f g a b c -> f (g a b c)
> indeed:
> >   f .:: g
> > = (((f .) .) . g) a b c -- structure equivalent to (x.g) a b c
> > = ((f .) .) (g a) b c   -- to (w .) (g a) b c   [with x = (w.) and w 
> = (f .)]
> > = ((f .) . (g a)) b c   -- to (w . (g a)) b c = (w . v) a b
> > = (f .) ((g a) b) c     -- to (f.) (v b) c = (f.) (g a b) c -- as v 
> = g a
> > = (f  . (g a b)) c      -- to (f . k) c   [with k = (g a b)]
> > = f ((g a b) c) = f (g a b c)  -- to f (k c)
> which is what we thought (.::) was.
> simply put, every dot in
> > (((f .) .)  .  g)  a  b  c
> 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);
> > ((f .) . (g a))  b  c -- first dot was used
> 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)
> > (f . (g a b))  c -- second dot was used
> 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:
> > f (g a b c)
>
> I hope it clarifies everything for anyone interested and that didn't 
> know it already, of course.
>
>
>
> Le vendredi 20 mai 2016, Tilmann <t_gass at gmx.de 
> <mailto:t_gass at gmx.de>> a écrit :
> > Thank you for the references. I like the term 'bind2'. I had a look 
> at Prelude.Generalized. Wow!
> >
> > bind2 = join .:: liftM2;
> > (.::) = (.) . (.) . (.)
> >
> > Am 20.05.16 um 04:50 schrieb Silent Leaf:
> >
> > 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.) 
> http://hackage.haskell.org/package/prelude-generalize-0.4/docs/Prelude-Generalize.html#v:bind2 
> http://hackage.haskell.org/package/SimpleH-1.2/docs/Algebra-Monad.html#v:bind2 
> http://hackage.haskell.org/package/definitive-base-2.3/docs/Algebra-Monad-Base.html#v:bind2 
> your problem become btw then: > doIt = bind2 update a b
> >
> > _______________________________________________
> > Beginners mailing list
> > Beginners at haskell.org <mailto:Beginners at haskell.org>
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
> >
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160521/335a7db9/attachment.html>


More information about the Beginners mailing list