I always thought that the prerequisites for a pointfree function were to get the function arguments to the end of the definition. E.g.
-- This can be made pointfree quite easily:
let lengths x = map length x
let lengths' = map length
-- However this cannot:
let lengthz x = length `map` x
-- let lengthz' = length `map` (parse error)
I originally came across this reading this question. There we have this example:
agreeLen :: (Eq a) => [a] -> [a] -> Int
agreeLen x y = length $ takeWhile id $ zipWith (==) x y
-- This may look like it can easily be made pointfree, however it cannot
-- agreeLen' :: (Eq a) => [a] -> [a] -> Int
-- agreeLen' = length $ takeWhile id $ zipWith (==) (zipWith is applied to too few arguments)
So why can my first example be made pointfree, but the other two cannot?
-- However this cannot: let lengthz x = length `map` x -- let lengthz' = length `map` (parse error)
\x -> length `map` x
written point free is simply map length
. The infix backticks are just syntactical sugar. (As chepner points out, if you really want it you can use a section, i.e. (length `map`)
.)
agreeLen :: (Eq a) => [a] -> [a] -> Int agreeLen x y = length $ takeWhile id $ zipWith (==) x y -- This may look like it can easily be made pointfree, however it cannot
The key word here is "easily". Pretty much anything can be made point-free if you try hard enough. In this case, omitting the y
parameter is easy if we write agreeLen
in terms of (.)
rather than ($)
:
agreeLen x y = (length . takeWhile id . zipWith (==) x) y
agreeLen x = length . takeWhile id . zipWith (==) x
As for x
, we can handle it by treating the use of (.)
to compose zipWith (==) x
with the other functions as just another case of a value being modified with a function:
agreeLen x = (.) (length . takeWhile id) (zipWith (==) x)
agreeLen x = ((length . takeWhile id) .) (zipWith (==) x) -- cosmetical change
agreeLen x = (((length . takeWhile id) .) . zipWith (==)) x
agreeLen = ((length . takeWhile id) .) . zipWith (==)
It is not something you'd actually want to do in practice, but it is certainly possible.