I am trying to understand how to convert functions to point-free notation in Haskell. I saw this example, but it is more complicated than what I am looking for. I feel like I un
You were really close. Allow me to add one more $
to illustrate:
f x = (+) 5 $ (/) 8 $ x
It should be clear that the expression (+) 5
is a function that takes one numeric input and produces a numeric output. The same goes for the expression (/) 8
. So you take whatever number is input, x
, and first apply the (/) 8
"function", and then apply the (+) 5
"function".
Whenever you have a chain of functions separated by $
, you can replace all except the rightmost with .
Meaning, if you have a $ b $ c $ d
, this is equivalent to a . b . c $ d
.
f x = (+) 5 . (/) 8 $ x
At this point, let's actually remove the $
and parenthesize instead.
f x = ((+) 5 . (/) 8) x
Now it should be clear that you can remove the trailing x
from both sides:
f = (+) 5 . (/) 8
That is the main idea. If you have f x = expr x
, you can "eta reduce" it to f = expr
. In order to produce pointfree code, you need simply recognize how the larger function is composed of smaller functions. Partial application is sometimes necessary for point free code (as in this case, (+) 5
and (/) 8
are partially applied). The "pointfree" program is quite helpful for when you don't want to think about it; Lambdabot on the #haskell irc channel uses this program as a plugin, so you don't even have to install it yourself; just ask:
@pl let f x = 5 + 8 / x in f
(5 +) . (8 /)