About This Series
This is the fourth 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.
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 = let sorted = List.sort names texts = List.map Html.text sorted textToItem text = Html.li  [ text ] items = List.map textToItem texts in 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:
namesis defined as a
Listof strings. Bonus points if get the reference.
mainfunction 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
mainfunction is divided into two parts:
- in the
letpart we define a bunch of things
- which are then used in the
- in the
sorted: We use
List.sortto sort the list of names in alphabetical order.
texts: We use
List.mapto apply the function
Html.textto 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).
textToItemdefines a new function on the fly, it takes one HTML text element and wraps it in an HTML
li(list item) element, representing an
items: We use
List.mapagain to apply our brand new
textToItemfunction to each element in the
textslist. The result is a list of HTML
- Finally, in the
inpart of the
mainfunction, we wrap the list of
lielements in an HTML
ulelement, rendering them as an
<ul>bullet point list.
You might have noticed the odd empty list
 literal when we used the
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 names = [ "Pearl", "Steven", "Garnet", "Amethyst" ] main = let sorted = List.sort names texts = List.map Html.text sorted textToItem text = Html.li [ Html.Attributes.style [("font-style", "italic") ] ] [ text ] items = List.map textToItem texts in Html.div [ 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.