# Functions

We have already seen functions in sections about basic datatypes and evaluating expressions. In this section, we explore the how the functions work and introduce the concepts of 'function literals', and functions as values.

## Function literals

In addition to predefined functions, such as reverse, we can also define our own. The most primitive way of achieving this is to use function literals, which are literal representation1 for function values.

As an example, the following is a function that multiplies its argument by itself and subtracts one:


\x -> x * x - 1



In the above, the variable between \ and -> is the parameter of the function. When the function is called, all occurences of this parameter in the left of the -> are replaced by the argument of the function. The name of the parameter does not matter, and the above could have been equivalently written as (\y -> y * y - 1) or even (\number -> number * number - 1).

Like predefined functions, the only operation on function literals is application. For example, we can apply the above function to the value 10:


(\x -> x * x - 1) 10
== {- Function application, x:=10 -}
10 * 10 - 1
== {- Arithmetic -}
99



Function literals, like other values, can be given a names. You can do this in GHCi session by using let-statements. This allows you to re-use function literals:

GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
Prelude> let firstFunction = \x -> x * x - 1
Prelude> let oneMore = \x -> x+1
Prelude> firstFunction 2
3
Prelude> oneMore (firstFunction 2)
4

Alternatively, you can save your function definitions in a file and load them with GHCi. See Section 'Saving declarations to modules' for further details on how to do this.

### Worked example: Evaluating an expression with function literals.


myFunction = \x -> x * x - 1


evaluate expression myFunction 5.


myFunction 5
== {- Definition, myFunction = \x -> x*x-1 -}
(\x -> x*x-1) 5
== {- Function application, x := 5 -}
5*5-1
== {- Arithmetic -}
24


### Worked example: Function as argument and return value.

This example demonstrates that functions can be passed as arguments and used as return values.


myFunction = \x -> x * x - 1
twice      = \f -> (\x -> f (f x))


evaluate twice myFunction 5.


twice myFunction 5

== {- Definition, twice = \f -> (\x -> f (f x)) -}
(\f -> (\x -> f (f x))) myFunction 5

== {- Application, f := myFunction-}
(\x -> myFunction (myFunction x)) 5

== {- Application, x := 5 -}
myFunction (myFunction 5)

== {- Definition, myFunction = \x -> x*x-1 -}
(\x -> x*x-1) (myFunction 5)

== {- Application, x := (myFunction 5) -}
(myFunction 5) * (myFunction 5) - 1

== {- According to the previous calculation,  myFunction 5 == 24 -}
24 * 24 - 1


Notice how the evaluation is purely mechanical and how function application works on purely symbolic level. We do not really care what (myFunction 5) actually is when we replace f with it. All that matters is that we write it in the place of f.

You can try out more examples below:

When faced with a difficult Haskell expression, try to calculate its value with pen and paper. This will clarify to you how the expression works.

## Functions with multiple parameters

The function literals above have only a single parameter. This seems restricive. What if we would need a function to calculate the area of a rectangle based on its width and height? Although this operation requires are two parameters, it can be represented with the uniparameter function literals we just saw.

First, we suppose that the height is constant and make a function which takes the width as a parameter:


(\width -> width * height)


Next, we perform a trick known as 'currying', and return the above function from another function that takes the height as a parameter:


(\height -> (\width -> width * height))


Now, this construct can be supplied two parameters, one after another:


(\height -> (\width -> width * height)) 5 3
== {- function application is right associative, so this is same as -}
((\height -> (\width -> width * height)) 5)   3
== {- function application, height := 5 -}
(\width -> width * 5)   3
== {- function application, width := 3 -}
3 * 5
== {- arithmetic -}
15


## Writing function definitions

To avoid writing the above function every time we wish to calculate an area, we give it a name and save it to a file:


module Rectangle where
-- You can write this to file Rectangle.hs and
-- load it in GHCi with command ghci Rectangle.hs

rectangleArea = \height -> (\width -> width * height)


Since \height -> (\width -> width * height) is quite complex to write, Haskell allows you to shorten it to:


\height width -> width * height


Furthermore, if you intended to give the function a name, it can be written even more concisely as:


rectangleArea2 height width = width * height


Remember that this means the same as the original definition with function literals.

Similarly, we often omit converting the function name into a function literal before applying it and calculate like this:


rectangleArea2 5 3
== {- definition of rectangleArea2, height:=5, width:=3 -}
3 * 5
== {- arithmetic -}
15


### Drills

Check your understanding. Which of the below is the result of the application f a, if f = \x -> reverse x and a = words "a cat"?

• reverse words "a cat"

This would mean that words is passed as argument to reverse, whereas in the equation of f reverse is given the whole x.

• reverse (words "a cat")

This is correct.

Check your understanding. Which expressions below are equivalent to the expression f a, given the definitions f = \x -> \y -> (x++y++x), a = reverse y and y = "cat"

• \y -> (reverse y ++ y ++ reverse y)

With argument "dog" this would evaluate to "goddoggod".

• \z -> (reverse y ++ z ++ reverse y)

With argument "dog" this would evaluate to "tacdogtac". Note that we have renamed the the argument y to z to differentiate it from the y in reverse y. The y there is totally different variable.

• \y -> (reverse x ++ y ++ reverse x)

This is an error, since x is not defined.

## Partial application

Functions can be partially applied. For example, rectangleArea 5 is a valid Haskell expression, which denotes a function from width to area of a rectangle. This can be used to build new definitions, such as,


areaOfRectangleWithHeight5 = rectangleArea 5


The meaning of areaOfRectangleWithHeight5 can be seen by calculating its value:


areaOfRectangleWithHeight5'

== {- Definition -}
rectangleArea 5

== {- Value of rectangleArea -}
(\height -> (\width -> width * height)) 5

== {- Function application, height := 5 -}
\width -> width * 5


That is, areaOfRectangleWithHeight5 is just a function that multiplies it argument by five.

Besides being useful in creating specialized functions, partial application is especially useful with predifined functions such as map (see definition of map)


map (rectangleArea 5) [1,2,4]
== {- definition of rectangleArea -}
map ((\height -> (\width -> width * height)) 5) [1,2,4]
== {- Function application, height := 5 -}
map (\width -> width * 5) [1,2,4]
== {- Map applies the function to all elements of the list -}
[(\width -> width * 5) 1 ,(\width -> width * 5) 2 ,(\width -> width * 5) 4]
== {- function applications with width:=1, width:=2, width:=4, respectively -}
[1 * 5, 2 * 5, 4 * 5]
== {- Arithmetic -}
[5,10,20]


### Drills

Check your understanding. Which of the expressions below are equivalent to the expression (\x -> (\x -> x*x)) 5?

• 5

The return value of (\x -> (\x -> x*x)) is a function: (\x-> x*x)which cannot reduce to a number.

• 5*5 or 25

The return value of (\x -> (\x -> x*x)) is a function: (\x-> x*x)which cannot reduce to a number.

• \5 -> (\x -> x*x)

This is just nonsense.

• \5 -> (\5 -> 5*5)

This is just nonsense.

• \x -> x*x

Notice that the first and the second x are different. For clarity, we could write the original expression as \x -> (\y -> y*y).

• \x -> 5*x

Notice that the first and the second x are different variables. The xs in x*x all refer to the second x.

• (\i -> (\j -> j*j)) 5

Consistently renaming variables does not affect the value of the expression.

## Explicit application ($) and function Composition (.) Function application is denoted by writing the argument after the function name separated by a space. Everything that is not an operator is passed on as a parameter, which sometimes makes it difficult to pass a result of a function as a parameter to another. Consider, Download sample  reverseWords str = reverse (words str) -- vs. nonSense str = reverse words str  Notice the need of parenthesis above. We can make function application explicit by defining a new operator called $ or 'apply':


f $x = f x infixr 0$



With the explicit application operator, we can write


reverseWords str = reverse $words str  This works because operators are not given as arguments to functions:  reverse$ words str
== {- Adding parenthesis for clarity -}
reverse $(words str) == {- Definition of$, f = reverse, x = (words str) -}
reverse (words str)


Function composition is denoted by symbol (.), which is defined like this


f . g = \x -> f (g x)
infixr 9 .



Similar to its use in mathematics, function composition is often used to build new functions by composing together other functions. For example, let us consider the task of reversing the order of words in a string:


reverseWords2 = unwords . reverse . words


The reverseWords2 definition defines a new function, even though we do not use function literals, or name the parameters. Again, this is obvious by simple calculation:


reverseWords2

== {- Definition-}
unwords . reverse . words

== {- (.) is right associative -}
unwords . (reverse . words)

== {- Application, f . g = \x -> f (g x), and f := reverse, g := words -}
unwords . (\x -> reverse (words x))

== {- Application, f . g = \x -> f (g x), and f := unwords, g := \x -> .. -}
\x -> unwords ((\x -> reverse (words x)) x)

== {- Notice the to different variables named x. For clarity, rename one of them to y -}
\y -> unwords ((\x -> reverse (words x)) y)

== {- Application, x := y -}
\y -> unwords (reverse (words y))


Function composition and explicit application have many different uses, but perhaps the most common usage is to construct chains of operations such as f . g . h . j $x. ### Drills Check your understanding. Which of the expressions below are equivalent to the expression f . g . h . j$ x?

• (((f g) h) j) x

. is not left associative.

• (f . g) . (h . j) $x Function composition is an associative operation, so the expression can be regrouped at will. (Think: Why is (.) associative?) • g . f . h . j$ x

Function application is not commutative. Consider (reverse . length) vs. (length . reverse)

• f $g$ h $j$ x

The $-operator is also right associative, so this is same as (f$ (g $(h$ (j $x)))) == f (g (h (j x))) == f . g . h . j$ x

• f (g (h (j x)))

This is what you get by applying definitions of . and \$

• f . g . h . (j x)

Where the original meant x applied to j applied to f . g . h, this means j x composed to f . g . h. Most importantly, this implies that j applied to xis a function.

## Exercises

### Exercise -- Practise evaluation

1. Derive, without a computer, the result of expression (\x -> x 2 * 2) (\x -> x+x)
2. Derive, without a computer, the result of expression unwords . map sort . words
3. Given the definition f = \x -> x:f (x+1), derive the result of expression f 5. (The operator : adds an element to the head of a list. See here)

(Firefox temporarily unsupported. Use chrome)

1. A literal value is the concrete textual representation for abstract values. For example, the characters 1 and 2 form the literal representation for the value 12. In the same way, the characters \x->2*x represent a function that doubles its argument.

## Give feedback on:

[TOPIC]

Clarity of presentation

Difficulty of the topic (1 star=easy, 5 stars=very hard)

Interestingness of the topic