Working with functions

Here's an example of a pure function:

1 2 | ```
f :: Int -> Int
f = \x -> x + 1
``` |

The function above adds one to its input to produce the output. Note that the type of a function contains an arrow -> also called the function type constructor, a special type constructor that's built into the compiler. Note that the same operator -> is also used when constructing the lambda expression \x -> x + 1.

As functions are extremely common, we use the syntax below:

1 2 | ```
f :: Int -> Int
f x = x + 1
``` |

We've looked at single-input functions. What about multi-input functions? We know the (->) type constructor only takes two inputs, so do we need a new type constructor for every number of inputs? Not necessarily. What if we created nested lambda expressions?

1 2 3 4 5 6 7 8 | ```
g :: (Int -> (Int -> Int))
g = \x -> \y -> x + y
g1:: Int -> (Int -> Int)
g1 x = \y -> x + y
g2 :: Int -> Int -> Int
g2 x y = x + y
``` |

Note that g, g1, g2 are all equivalent.

As you can see, for multi-input functions, we supply an input one at a time in the expected order until all the lambdas have been eliminated, at which point the function is evaluated completely into the resultant value.