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 understand the logic behind it, but when I am trying to execute some simple examples in code I am getting compile errors. I want to try and write this function in point-free style:
f x = 5 + 8/x
which I rearranged as f x = (+) 5 $ (/) 8 x
So, I thought it might be something like this:
f = (+) 5 $ (/) 8
but when I run this in ghci I get this message:
No instance for (Num (a0 -> a0))
arising from the literal `5' at Test.hs:3:9
Possible fix: add an instance declaration for (Num (a0 -> a0))
In the first argument of `(+)', namely `5'
In the first argument of `($)', namely `(+) 5'
In the expression: (+) 5 $ (/) 8
Failed, modules loaded: none.
I don't understand the "No instance for..." message. What do I need to do to write this function in point-free style?
Pointless Haskell is a library for point-free programming with recursion patterns defined as hylomorphisms. It also allows the visualization of the intermediate data structure of the hylomorphisms with GHood. This feature together with the DrHylo tool allows us to easily visualize recursion trees of Haskell functions.
Tacit programming, also called point-free style, is a programming paradigm in which function definitions do not identify the arguments (or "points") on which they operate. Instead the definitions merely compose other functions, among which are combinators that manipulate the arguments.
Advertisements. Functions play a major role in Haskell, as it is a functional programming language. Like other languages, Haskell does have its own functional definition and declaration. Function declaration consists of the function name and its argument list along with its output.
No. However, you can have functions that return a trivial value. The () type has only one inhabitant, () .
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:
<DanBurton> @pl let f x = 5 + 8 / x in f
<lambdabot> (5 +) . (8 /)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With