Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting expression to pointfree style (Haskell)

I wrote this code and I have to rewrite it to the pointfree style:

num_of_occ ele list = length(filter(==ele)list) 

So I did this:

num_of_occ ele = length . filter((==)ele)

It works. Than I did this:

num_of_occ = length . filter . (==)

And it doesnt... what's wrong with my line of thought?

like image 648
ciembor Avatar asked Nov 28 '12 01:11

ciembor


1 Answers

This is a common error. Here is the fix:

num_of_occ = (length .) . filter . (==)

It has to do with the number of arguments your function takes. The function composition (.) operator works on functions with one argument, you need to apply it twice (f .) . to make it work on functions with two arguments.

There's actually a program on Hackage that will automatically convert a snippet of code to points free style, if you want to play with it.

$ cabal install pointfree
$ pointfree 'num_of_occ ele list = length (filter (== ele) list)'
num_of_occ = (length .) . filter . (==)

As noted, this needs a type signature to work correctly. The reasons for this are relatively mundane but obscure, and the restriction exists to improve Haskell performance. You can turn on the NoMonomorphismRestriction extension, or add a type signature:

num_of_occ :: Eq a => a -> [a] -> Int
num_of_occ = (length .) . filter . (==)
like image 148
Dietrich Epp Avatar answered Sep 18 '22 19:09

Dietrich Epp