# Functions

Recall the following from before:

``````doubleList xs = map ((*) 2) xs

squareList xs = map square xs
where square x = x ^ 2``````

The latter defines a helper definition to be used just once. There are several ways to avoid this: with lambdas, by flipping the order of function arguments, and with sections. No matter which version we choose, we can further simplify the definition via eta-reduction.

``````squareList xs = map (\x -> x ^ 2) xs   -- lambda
squareList xs = map (flip (^) 2) xs    -- flip
squareList xs = map (^2) xs            -- section
squareList    = map (^2)               -- eta-reduction``````

## Lambdas

All function definitions we have seen so far are syntactic sugar.

``````addOne x = 1 + x  ===  addOne = \x -> 1 + x

add x y  = x + y
===  add = \x -> \y -> x + y    -- nested lambda
===  add = \x y -> x + y        -- sugar for nested lambdas``````

Arrows associate to the right (in expressions and in types)

`````` S ->  (T ->  U)

\x -> (\y ->  e)

x :: S
y :: T
e :: U``````

So, "multi-argument" functions:

``````e1 e2 e3 e4 e5  ===  ((((e1 e2) e3) e4) e5)

e1 :: T2 -> (T3 -> (T4 -> T5))
e2 :: T2
e3 :: T3
e4 :: T4
e5 :: T5``````

## Function Application and Composition

### Flipping Arguments

Flip the order of first two arguments to a function.

``````flip :: (a -> b -> c) -> b -> a -> c
flip f y x = f x y``````

### Currying / Uncurrying

``````curry :: ((a, b) -> c) -> a -> b -> c
curry f a b = f (a, b)

uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f (a, b) = f a b``````

### Infix Application

Infix function application, along with its `r`ight-associative fixity declaration, allows nested function calls to be right-associated without writing so many parentheses. Don't worry too much about precedence levels (here `0`) for infix operators.

``````infixr 0 \$

(\$) :: (a -> b) -> a -> b
(\$) f x = f x``````

Note that infix operators can be defined in infix style:

``f \$ n = f x``

Left- vs. right-associated nested function calls:

``````        e1 e2 e3 e4 e5  ===  ((((e1 e2) e3) e4) e5)

(e1 (e2 (e3 (e4 e5))))  ===  e1 \$ e2 \$ e3 \$ e4 e5``````

### Pipeline Application

The `\$` operator can improve the clarity of a "backward pipeline" of function calls. The expression

``double \$ square \$ double \$ 3``

can be read "pipe" `3` into the `double` function, then pipe its result to the `square` function, then pipe its result to the `double` function. Choosing `(<|)` to denote this operator, rather than `(\$)`, may make the backward pipelining more visually apparent:

``double <| square <| double <| 3``

We can also define a "forward pipeline" operator:

``````(|>) :: a -> (a -> b) -> b
x |> f = f x``````

For example:

``3 |> double |> square |> double``

Or, when each of the functions gets too long to fit on a line:

``````x |> fReallyReallyReallyLongExpression
|> gReallyReallyReallyLongExpression
|> hReallyReallyReallyLongExpression``````

Using operators to `(<|)` and `(|>)` denote backward and forward pipelining is common in other functional languages like OCaml and Elm. In Haskell, however, the operators `(\$)` and `(&)` (defined in `Data.Function`) are the norm.

### Composition

``````compose :: (b -> c) -> (a -> b) -> a -> c
compose f g x = f (g x)``````

Infix operator composition.

``(.) f g x = f (g x)``

Alternate definition.

``(f . g) x = f (g x)``

Point-free notation. A "point" is an explicit, named argument, not the `(.)` operator.

``````squareAndDouble x = compose double square x
squareAndDouble   = compose double square
squareAndDouble   = double . square``````

## Sections

A section is the partial application of a binary operator to one of its arguments.

``````(n op) === (op) n === (\m -> n op m)

(op m) === flip (op) m === (\n -> n op m)

> (+3) 4
> let plus3 = (+3)      -- let plus3 x = x + 3
> (3+) 4
> let plus3 = (3+)      -- let plus3 x = 3 + x
> (*1) == (1*)
> (1-) 10
> (-1) 10               -- special case: unary minus!
> (subtract 1) 10       -- poor man's "section"
> (^) 2 3
> (^) 2
> flip (^) 3``````

Speaking of binary operators, we have seen how infix operators can be used as prefix functions.

``> (+) 1 2``

Prefix functions can also be used as infix operators.

``````> let plus = (+)
> 1 `plus` 2``````

## Eta-Reduction

``````f x = g x
f   = g

f x = (BIG_COMPLICATED_EXPRESSION) x
f   = (BIG_COMPLICATED_EXPRESSION)``````

Note that this eta-reduction pattern is only valid if `x` is not referred to in the `BIG_COMPLICATED_EXPRESSION`.

For example:

``````double x = (2*) x
double   = (2*)

square x = (^2) x
square   = (^2)

squareAndDouble x = compose (*2) (^2) x
squareAndDouble   = compose (*2) (^2)
squareAndDouble   = (*2) . (^2)

squareAndDoubleList xs = map squareAndDouble xs
squareAndDoubleList xs = map ((*2) . (^2)) xs
squareAndDoubleList    = map ((*2) . (^2))``````