[Haskell-cafe] Re: Exercise in point free-style

Lennart Augustsson lennart at augustsson.net
Fri Sep 1 20:36:08 EDT 2006


An easy way to solve this is to ask lambdabot.  Log on to the Haskell  
IRC channel:
lennart: @pl  \ f l -> l ++ map f l
lambdabot: ap (++) . map

Notice how it's much shorter than the Hughes' solution. :)

	-- Lennart

On Sep 1, 2006, at 13:11 , John Hughes wrote:

>> From: Julien Oster <haskell at lists.julien-oster.de>
>> Subject: [Haskell-cafe] Exercise in point free-style
>>
>> I was just doing Exercise 7.1 of Hal Daumé's very good "Yet Another
>> Haskell Tutorial". It consists of 5 short functions which are to be
>> converted into point-free style (if possible).
>>
>> It's insightful and after some thinking I've been able to come up  
>> with
>> solutions that make me understand things better.
>>
>> But I'm having problems with one of the functions:
>>
>> func3 f l = l ++ map f l
>>
>> Looks pretty clear and simple. However, I can't come up with a  
>> solution.
>> Is it even possible to remove one of the variables, f or l? If so,  
>> how?
>>
>> Thanks,
>> Julien
>
> Oh, YES!!
>
> Two ways to remove l:
>
> func3a f = uncurry ((.map f).(++)) . pair
> func3b f = uncurry (flip (++).map f) . pair
>
> And just to make sure they're right:
>
> propab new f l =
>  func3 f l == new f l
>  where types = f :: Int->Int
>
> quickCheck (propab func3a)
> quickCheck (propab func3b)
>
> If you don't mind swapping the arguments, then
>
> propc f l =
>  func3 f l == func3c l f
>  where types = f :: Int->Int
>
> func3c l = (l++) . (`map` l)
>
> With the arguments swapped, you can even remove both!
>
> propd f l =
>  func3 f l == func3d l f
>  where types = f :: Int -> Int
>
> func3d = uncurry ((.(flip map)) . (.) . (++)) . pair
>
> MUCH clearer!
>
> The trick is to observe that l is duplicated, so you need to use a  
> combinator that duplicates something. The only one available here  
> is pair, which you then have to combine with uncurry.
>
> It would be nicer to have
>
> (f &&& g) x = (f x,g x)
>
> available. (&&& is one of the arrow combinators). Then you could  
> remove l by
>
> func3e f = uncurry (++) . (id &&& map f)
>
> which is sort of readable, and remove both by
>
> func3f = (uncurry (++).) . (id &&&) . map
>
> John
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list