3

In a Codefights challenge where you have to add two numbers the user kaiochao had a super minimalisic answer

add = (+)

How does it work and has this functionality a own name?

3
  • 2
    It's called "pointfree", it's an inherent property of the lambda calculus Haskell is built on. Commented Oct 23, 2017 at 13:10
  • 4
    The author could have written add x y = x + y, which is another way of saying add = \x y -> (+) x y (ie, add is a function with parameters x and y which applies the function (+) to x and y). You can eta-reduce this to elide the two arguments. Commented Oct 23, 2017 at 13:13
  • depends on what you mean by "it". the parens around the +? the = sign? the name without the arguments? Commented Oct 23, 2017 at 20:45

2 Answers 2

8

Here's an explicit definition:

add a b = a + b

There is a feature in Haskell that says that we can rewrite a + b as (+) a b, this is due to the fact that operators are functions in Haskell. So we can rewrite:

add a b = (+) a b

But then we're doing nothing extra to the arguments of this function, so we can reduce this function by removing the explicit arguments*. Note that this requires an understanding of how function application in Haskell works:

add = (+)

This is because functions are data in Haskell. This is literally saying that plus and the function of addition are the same thing.

In practice, we can see this by substituting:

  add 1 2
= (+) 1 2 -- Since add = (+), this can be read literally.
= 1 + 2   -- This is how operators work in Haskell.
= 3       -- Calculation.

This is known as pointfree style in Haskell.


*As @Benjamin Hodgson mentioned, this is called eta-reduction.

Sign up to request clarification or add additional context in comments.

Comments

5

This “functionality” is just variable assignment. It works the same way as writing

three = 3

3 is just a Haskell value, which I can at any point give a new name, refer to it, and get something that's (at least, at runtime) indistinguishable from 3 itself.

The fact that add has a somewhat more complicated type, namely a function type, changes nothing about the way such variable assignments work. I can certainly define

root = sqrt

...and then evaluate root 4 to obtain 2.0 as the result. Or, for any custom function,

foo :: Int -> String
foo n = concat $ replicate n (show n)

bar = foo

GHCi> bar 3
"333"
GHCi> bar 7
"7777777"

All that is really no different from how I can also write

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import math

In [2]: root = math.sqrt

In [3]: root(4)
Out[3]: 2.0

What's a bit more interesting about add is that + is an infix operator (because it consists of non-letter characters). But Haskell allows using such infix operators pretty much just as liberally as any other variables, including that you can define your own. The only thing that's a bit different are the parsing rules. + can not be a standalone syntactic unit but has to be surrounded on each side with with arguments you want to add, or with parentheses. The latter, (+), is really what the plus operator is from the compiler's point of view: the binary function, not yet applied to any arguments. So, when you want to give this operator a new name, you need to write

add = (+)

Incidentally, you could also give it a new operator-name, like

(⊕) = (+)

...that could then be used like 3 ⊕ 4, just as you can with the standard + operator.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.