[Haskell-beginners] Points-free style

Daniel Fischer daniel.is.fischer at googlemail.com
Sun Jun 5 17:40:19 CEST 2011


On Sonntag, 5. Juni 2011, 17:09, Alexander Shendi wrote:
> Hi folks,
> 
> I am working my way through "Learn You a Haskell for Great Good" and
> have reached page 84, where the book recommends that you define your
> functions in a "points-free style", using the "." and "$" operators.
> 
> Now I have:
> 
> sumProducts' :: Num a => [a] -> [a] -> a
> sumProducts' x y = sum (zipWith (*) x y)
> 
> I would like to eliminate the "x" and the "y" in the definition, but all
> I have managed to contrive is:
> 
> sumProducts :: Num a => [a] -> [a] -> a
> sumProducts x = sum . zipWith (*) x
> 
> How do I proceed from here? Any advice is welcome :)
> 
> Many thanks in advance,
> 
> /Alexander

First, (mentally) insert parentheses:

sumProducts x = sum . (zipWith (*) x)

Now, write the composition as a prefix application of (.),

sumProducts x = (.) sum (zipWith (*) x)
= ((.) sum) (zipWith (*) x)

which has the form f (g x), with f = (.) sum and g = zipWith (*), so it's

(f . g) x, which expands to

(((.) sum) . (zipWith (*))) x

and now the argument can easily be dropped, giving

sumProducts = ((.) sum) . (zipWith (*))

now to make it look a little nicer, we can remove unnecessary parentheses 
and write (.) sum as a section,

sumProducts = (sum .) . zipWith (*)

Generally, pointfreeing goes

f (g x) ~> f . g
f (g x y) ~> (f .) . g
f (g x y z) ~> ((f .) .) . g

Play with it and get a little experience, but don't overuse it.
Nobody really wants to come across a pointfree version of

\a b c d e f g h -> foo (bar a b) (baz c d e) f (quux g h)

(and that's not even repeating or flipping arguments)



More information about the Beginners mailing list