Beliebte Suchanfragen
//

Elm Friday: Functions (Part V)

20.11.2015 | 4 minutes of reading time

Elm is a functional language, so naturally, functions and function calls are pretty important. We have already seen some functions in the previous episodes. This episode goes into more detail regarding function definition and function application.

About This Series

This is the fifth post in a series of short and sweet blog posts about Elm . The stated goal of this series is to take you from “completely clueless about Elm” to “chief Elm guru”, step by step. If you have missed the previous episodes, you might want to check out the table of contents .

Functions

This is a function definition in Elm:


multiply a b = a * b

The function definition starts with the name of the function, followed by the parameter list. As opposed to C-style languages like Java, JavaScript and the likes, there are no parentheses or commas involved, the parameters are only separated by spaces.

The equals character = separates the function name with the parameter list from the function body. The function body can be any Elm expression that produces a value. We can reference the parameters in the function body.

Function definitions can use other functions in their body. This is how this looks like:


square a = multiply a a

Here, we define a square function by using the multiply function we defined earlier. Function calls also don’t need any parentheses, just list the function parameters you want to pass into the function separated by whitespace.

You do need parentheses when you have nested expresssions:


productOfSquares a b = multiply (square a) (square b)

You can also declare anonymous functions (also known as lambda expressions) on the fly:


incrementAll list = List.map (\ n -> n + 1) list

This thing wrapped in (\ and ) is an anonymous function that takes one parameter and returns the parameter, incremented by one. This anonymous function is then applied to all elements in a list by using List.map.

Actually, we could have written this shorter. The following is equivalent:


incrementAll2 = List.map (\ c -> c + 1)

Why is that the same? Because Elm supports something called currying. incrementAll defines a function that takes a list and produces another list. incrementAll2 also defines a function, but it is a function that takes no arguments and returns another function.

So when we write incrementAll2 [1, 2, 3] Elm first evaluates incrementAll2, gets a function and then procedes to put the remaining arguments ([1, 2, 3] in this case) into this function. The result is the same.

If you find it hard to wrap your head around currying, don’t worry about it too much for now. You can always resort to write a more verbose version of your function without currying and come back to this concept later. As a rule of thumb, if the last element in the parameter list in the function declaration is simply repeated at the end of the function body (like list in this case), you can probably omit both.

Let’s wrap this up. Here is a complete, working Elm program that uses the functions we defined above:


import Html

multiply a b = a * b

square a = multiply a a

productOfSquares a b = multiply (square a) (square b)

incrementAll list = List.map (\ c -> c + 1) list

incrementAll2 = List.map (\ c -> c + 1)

main = Html.p []
  [ Html.text ("3 × 5   = " ++ (toString (multiply 3 5)))
  , Html.br [] []
  , Html.text ("4²      = " ++ (toString (square 4)))
  , Html.br [] []
  , Html.text ("2² × 3² = " ++ (toString (productOfSquares 2 3)))
  , Html.br [] []
  , Html.text ("incrementAll [1, 2, 3] = " ++ (toString (incrementAll [1, 2, 3])))
  , Html.br [] []
  , Html.text ("incrementAll2 [1, 2, 3] = " ++ (toString (incrementAll2 [1, 2, 3])))
  ]

What happens in these lengthy expressions in the main function? Well, the functions we defined return mostly numbers (or lists, in the case of incrementAll). So we need to convert their results into strings via the toString function (which comes from the Basics package and is imported by default). We then use ++ to append the resulting string to a string literal ("3 × 5 = ", for example) and use Html.text to convert the string into an HTML text node.

Fancy Function Application

Whoa, did you see what we did there to bring the result of one of our functions to the screen? Let’s take a look at Html.text ("3 × 5 = " ++ (toString (multiply 3 5))) for a moment. That’s a lot of parentheses right there. Elm has two operators, |> and <|, to write expressions like that in a more elegant fashion.

  • |>: Take the expression to the left of the operator and put it into the function on the right hand side.
  • <|: Take the expression to the right of the operator and put it into the function on the left hand side.

Here is the main function of the previous program, rewritten with the new operators:

main = Html.p []
  [ Html.text next episode, where we will take a look at type annotations.

share post

//

More articles in this subject area

Discover exciting further topics and let the codecentric world inspire you.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.