{{ message }}

Instantly share code, notes, and snippets.

# mauroc8/Functions in elm.md

Last active Feb 12, 2021

# Functions in Elm

Elm is the simplest language I know. Whenever possible, there's only one way of doing things.

Functions in elm can only take one argument. For example:

`\n -> n + 1`

That function takes one number, called `n` and returns the next number. The function is an anonymous function, but we can give it a name:

`addOne = \n -> n + 1`

Remember that in elm there's only one way of doing things? Well, this is an exception, because we can also define the function `addOne` the following way:

`addOne n = n + 1`

We can annotate the type for the function `addOne` as:

`addOne : Int -> Int`

This means that it takes any value of type `Int` and returns an `Int`.

"But wait," you may be thinking, "what's the point of a language where functions can take only one argument? That's useless!"

Actually, that follows from the "only one way of doing things" premise. As it turns out, we can define a function that takes two arguments using two functions that take only one argument each. For example, we can define a function that takes an `Int`, and returns a function that takes another `Int` and returns an `Int`.

`add = \n -> \m -> n + m`

This function can also be written:

```add = \n m -> n + m
add n m = n + m```

How would we annotate the type for `add`?

`add : Int -> (Int -> Int)`

As it turns out, the `->` (a.k.a. arrow) is right associative, which means that whenever a type expression using arrows has no parenthesis, the compiler infers parenthesis from right to left.

That's confusing, so let's see some examples. The following types are equivalent:

```add : Int -> (Int -> Int)
add : Int -> Int -> Int```

We can also take any function from the `elm/core` library as an example. For example, `Maybe.map`:

```map : (a -> b) -> Maybe a -> Maybe b
map : (a -> b) -> (Maybe a -> Maybe b)```

This also applies to functions that take more arguments:

```f : a -> b -> c -> d -> e -> f
f : a -> (b -> (c -> (d -> (e -> f))))```

Calling functions in elm is easy, we just say the name of the function and the argument, separated by a space:

`addOne 2 -- returns 3`

All functions take only one argument, so that's all there is to know when calling functions.

A function like `add`, that returns a function, can be called like this:

```add 1 -- returns a function equivalent to addOne: \m -> 1 + m
(add 1) 2 -- returns 3```

In the last line, we got a function from calling `add 1` and then we called that function with the argument `2`. As it turns out, function call is left associative, which means that whenever parenthesis are missing, the compiler places them from left to right.

That's confusing again, so we'll see some examples. The following are equivalent:

```add 1 2

f a b c d e
((((f a) b) c) d) e```

Appendix: Currying

In Javascript, when we have a function that takes several arguments we can convert them into a function that takes one argument and returns a function that takes another argument and returns a...

For example:

```function addTakingTwoArguments(x, y) {
return x + y;
}

The `add` function we wrote in elm is equivalent to `addTakingOneArgument`. The first function, `addTakingTwoArguments`, is impossible to write in elm, because all functions take only one argument!
The process of converting `addTakingTwoArguments` to `addTakingOneArgument` is called currying (named after Haskell Curry). One could say that all functions in elm are curried by default. In the elm community we usually don't use fancy names that might be confusing, that's why you probably won't hear about currying in the official guide, or in tutorials. I only mention it here because "currying" is a term common enough that you may have already heard it somewhere!