Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simple Haskell functions in point-free style

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?

like image 726
KJ50 Avatar asked Dec 11 '11 16:12

KJ50


People also ask

What is point-free Haskell?

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.

What is point-free code?

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.

What are Haskell functions?

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.

Can a Haskell function return nothing?

No. However, you can have functions that return a trivial value. The () type has only one inhabitant, () .


Video Answer


1 Answers

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 /)
like image 188
Dan Burton Avatar answered Sep 19 '22 22:09

Dan Burton