[Haskell-beginners] A little explanation! follow up

Dimitri DeFigueiredo defigueiredo at ucdavis.edu
Wed Apr 30 18:44:37 UTC 2014


Thanks everyone. It seems I asked the follow-up question too soon.
Michael's or David's proposed "reformulations"

elementAt_w'pf n xs = last (take (n + 1) xs)
or
elementAt_w'pf n = last . take (n + 1)

are so much easier to read than the original

elementAt_w'pf = (last .) . take . (+ 1)

that I will defer learning how to read the original version for now. It 
seems learning to quickly decipher that beast in one's head is not a 
prerequisite to being an effective haskell programmer. So, I'll just 
parse it at my slow pace for now. I think I can see how pointfree style 
(which I really like) can be overused sometimes.

Thanks again. This list rocks! :-)

Dimitri


Em 30/04/14 12:15, Brent Yorgey escreveu:
> On Wed, Apr 30, 2014 at 11:25:58AM -0600, Dimitri DeFigueiredo wrote:
>> I have a follow up question on this one. Is code like this:
>>
>> elementAt_w'pf = (last .) . take . (+ 1)
>>
>> considered good haskell?
> Uses of composition sections like (last .) is not very common; I would
> not consider it good haskell (though tastes may differ).  On the other
> hand, point-free notation, used in moderation, is considered good
> Haskell style. For example, instead of
>
>    foo x = bar (baz (quux x))
>
> you should write
>
>    foo = bar . baz . quux
>
> In this case I would certainly consider the second definition better
> style than the first.
>
>> If so, will this ever become easy to read?
>> What do I do to practice reading this?
> Just read and write lots of code.  Try transforming things into and
> out of point-free notation as an exercise.
>
>> More specifically, how would I know in mind head, before asking the
>> type checker in GHCi to write this pipeline with the section (last .)
>> instead of simply making the (wrong) pipe:
>>
>> elementAt_w'pf = last . take . (+ 1)
> Simply by working out the types in your head.  This becomes much
> easier with practice.
>
>> I am used to using pipes in the unix shell, but in the shell there is
>> always only one input and one output. There is no currying going on
>> and so it is very clear what we are dealing with. How do I learn
>> this?
> There is always only one input and one output in Haskell as well.  The
> thing that makes it more complicated is that unlike in the shell,
> those inputs and outputs can themselves be functions.
>
> -Brent
>
>>
>> Em 30/04/14 09:53, Kyle Murphy escreveu:
>>> Near as I can tell, this is basically having to do with partial
>>> application and the order of precedence for the (.) operator. A
>>> great way to look at this stuff is using the :t command in GHCi and
>>> checking out the types involved.
>>>
>>> Prelude> :t (.)
>>> (.) :: (b -> c) -> (a -> b) -> a -> c
>>>
>>> Prelude> :t last
>>> last :: [a] -> a
>>>
>>> Prelude> :t (last .)
>>> (last .) :: (a -> [c]) -> a -> c
>>>
>>> Looking back at the type for (.) and plugging in "[a]" in place of
>>> "b" and "a" in place of "c" we get:
>>> ([b] -> b) -> (a -> [b]) -> a -> b
>>>
>>> and since "last" takes the place of the first function we can
>>> reduce that to:
>>> (a -> [b]) -> a -> b
>>>
>>> GHCi used "c" where we used "b" but you can clearly see the
>>> signatures are identical other than that detail.
>>>
>>> What we're left with is, (last .) is used to take a function from
>>> some type "a" that returns a list of type "b", and a "a" value, and
>>> then returns the last value from that list of "b" types.
>>>
>>>
>>> -R. Kyle Murphy
>>> --
>>> Curiosity was framed, Ignorance killed the cat.
>>>
>>>
>>> On Wed, Apr 30, 2014 at 11:29 AM, Gilberto Melfe
>>> <gilbertomelfe at gmail.com <mailto:gilbertomelfe at gmail.com>> wrote:
>>>
>>>     Hello everybody !
>>>
>>>     Could someone explain me exactly how this function works?
>>>
>>>     elementAt_w'pf = (last .) . take . (+ 1)
>>>
>>>     It's a posted solution to: 99 Haskell problems, problem 3.
>>>
>>>     I'm having trouble with the "(last .) ." thing!
>>>
>>>     Hope someone can help!
>>>
>>>     Thank You!
>>>
>>>     Gilberto
>>>
>>>     _______________________________________________
>>>     Beginners mailing list
>>>     Beginners at haskell.org <mailto:Beginners at haskell.org>
>>>     http://www.haskell.org/mailman/listinfo/beginners
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> Beginners at haskell.org
>>> http://www.haskell.org/mailman/listinfo/beginners
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners



More information about the Beginners mailing list