# Partial Application of Functions in Elm

A friend of mine recently raised an interesting question. If a function takes two arguments, why is its type annotation `f: a -> b-> c`? Wouldn't something like `f: (a, b) -> c` make more sense?

A solid understanding of how Elm treats functions will make the answer clear and allow us to write better code.

#### One argument at a time

Let's take the following example:

``````greeting : String -> String -> String
greeting hello name = hello ++ ", " ++ name ++ "!"
``````

On the surface, this looks like a function that takes two arguments and returns a result:

``````greeting "Hello" "DailyDrip" == "Hello, DailyDrip!"
``````

However, functions in Elm always take exactly one argument and return a result (hence the function type annotation syntax).

Passing a single argument to our `greeting` function returns a new function that takes one argument and returns a string (commented-out output in the examples below comes from `elm-repl`):

``````helloGreeting = greeting "Hello"
-- <function> : String -> String
``````

Passing an additional argument to this partially applied function will yield the expected result:

``````helloGreeting "DailyDrip"
-- "Hello, DailyDrip!" : String
``````

This shows that the following notation is equivalent:

``````greeting "Hello" "DailyDrip" == ((greeting "Hello") "DailyDrip")
``````

Parentheses are optional because function evaluation associates to the left by default. Let's take a look at some examples where partial application is especially useful.

#### Expressive function definitions

Let's begin with a simple example of a function that doubles a number. Our first take could be:

``````double n = n * 2
-- <function> : number -> number
``````

The beautiful thing about Elm is that even operators are functions:

``````(*)
-- <function> : number -> number -> number
``````

We can use partial application to be more concise while achieving the same result:

``````double = (*) 2
-- <function> : number -> number
``````

Because `(*)` takes two numbers as arguments, the compiler will infer that our `double` function takes one number as its sole argument.

While a function to double all elements of a list could be written as:

``````doubleList list = List.map double list
-- <function> : List number -> List number
``````

by applying the same principle, we can do better:

``````doubleList = List.map double
-- <function> : List number -> List number
``````

#### Piping

Now that we know that operators are functions too, we can fully grasp how piping works:

``````(|>)
-- <function> : a -> (a -> b) -> b
``````

It really is no magic: the second argument is a function, which makes it one of the most common use cases for partial application. A good example to demonstrate it is the following function that returns the sum of all deposits:

``````amountDeposited : List Transaction -> Float
amountDeposited list =
List.filter (\t -> t.type_ == Deposit) list
|> List.map .amount
|> List.sum
-- rather than the nested equivalent:
-- List.sum (List.map .amount (List.filter (\t -> t.type_ == Deposit) list))
``````

There's one important design feature of Elm that makes all of this possible: data structure is always the last argument. This makes writing better, more idiomatic Elm code using piping and partial application a breeze.