Elm Friday: Hello World 2.0 (Part IV)

No Comments

About This Series


Hello World 2.0

This episode builds directly on the previous episode in which we built our first Hello World app in Elm. Printing a simple string is an amazing feat but surely Elm can do a bit more, right? Let’s take a first peek at how Elm works with data structures and renders them to HTML.

The following program sorts a list of names and renders them as an HTML list.

import Html

names = [ "Pearl", "Steven", "Garnet", "Amethyst" ]

main =
    sorted = List.sort names
    texts = List.map Html.text sorted
    textToItem text = Html.li [] [ text ]
    items = List.map textToItem texts
    Html.ul [] items

As with every code example, you are encouraged to put this into a file and have a look at the result in the browser by running it with elm-reactor.

This example introduces several new Elm concepts. Let’s go through them one by one:

  • names is defined as a List of strings. Bonus points if get the reference.
  • The main function is the entry point into our program, just as in the Hello World example. It is a bit more involved than the last time, though.
  • The body of the main function is divided into two parts:
    • in the let part we define a bunch of things
    • which are then used in the in part
  • sorted: We use List.sort to sort the list of names in alphabetical order.
  • texts: We use List.map to apply the function Html.text to each element in the list sorted. The result is a list of HTML text elements. (Elm does not render strings to HTML directly, you always have to turn strings into HTML text elements first).
  • textToItem defines a new function on the fly, it takes one HTML text element and wraps it in an HTML li (list item) element, representing an <li> tag.
  • items: We use List.map again to apply our brand new textToItem function to each element in the texts list. The result is a list of HTML li elements.
  • Finally, in the in part of the main function, we wrap the list of li elements in an HTML ul element, rendering them as an <ul> bullet point list.


You might have noticed the odd empty list [] literal when we used the Html.li and Html.ul functions. The reason for this is that nearly all functions from the Html module that yield an HTML tag take two arguments: a list of attributes and a list of inner elements. The first argument (the attributes) can be used to set a CSS class, inline styles, event listeners or anything else that is represented as an attribute in HTML. The second argument, the inner element list is the list of HTML elements that will be wrapped in the new HTML element.

Let’s look at this a bit closer. Here is a chunk of Elm that sets some inline styles to center the content on the page and set the font-style:

import Html
import Html.Attributes


main =
    sorted = List.sort names
    texts = List.map Html.text sorted
    textToItem text =
        [ Html.Attributes.style [("font-style", "italic") ] ]
        [ text ]
    items = List.map textToItem texts
      [ Html.Attributes.style
        [ ("position", "absolute")
        , ("width", "10em")
        , ("height", "10em")
        , ("top", "50%")
        , ("left", "50%")
        , ("transform", "translateX(-50%) translateY(-50%)")
        , ("overflow", "hidden")
      [ Html.ul [] items ]

We have one new import, the module Html.Attributes which bundles all attribute related functions. There are two differences to the previous example here: The li items now have a non-empty list of attributes. We use the function Html.Attributes.style to set their font-style. Also, we wrap the <ul> tag in a div, which also comes with a list of inline styles. Those styles center the div on the page.

We sneakingly introduced a new syntax element here. The style function takes a list of tuples. Tuples are a bit like lists in the very general sense that they represent collections of multiple individual items. There are two important differences: In a list, each element has the same type and lists have a variable length. The elements of a tuple can all have different types and tuples have a fixed length. The number of elements and their individual type is a part of the tuple’s type. Thus, you can’t pass a tuple with three elements (or one) into a function that expects tuples with two elements. In other words, tuples are just pairs (or triplets, quadruplets, …) of values. They are enclosed in ( and ) in Elm.

In this case, each style is a 2-tuple of strings and the argument to style is a list of such tuples.

This concludes the fourth episode of this blog post series on Elm. Make sure to check out the next episode, a deep dive into functions in Elm.

