Elm Friday: Union Types
In the last episode we took a look at some of the type constructs Elm provides, namely type aliases and records. We continue in this episode by looking at the last major type construct, union types.
About This Series
This is the tenth 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 .
Union Types
Union types are similar to enumerations, which you might know from other languages. A simple union type could look like this:
type Fruit = Apple | Banana | Orange
This declares a new union type that has three possible values (Apple
, Orange
and Banana
in this example).
Union types and case statements are a perfect match, so this is a good time to introduce the case
statement:
module Main (..) where
import Html exposing (..)
type Fruit
= Apple
| Banana
| Orange
fruitToProverb : Fruit -> String
fruitToProverb fruit =
case fruit of
Apple -> "An apple a day keeps the doctor away"
Banana -> "Time flies like an arrow; fruit flies like a banana."
Orange -> "An orange never bears a lime."
main : Html
main =
ul
[]
[ li [] [ Apple |> fruitToProverb |> text ]
, li [] [ Banana |> fruitToProverb |> text ]
, li [] [ Orange |> fruitToProverb |> text ]
]
The case-of statement in the fruitToProverb
function takes an expression (in this case the fruit
parameter) and matches it against all listed cases. The branch that matches will be used. So, if you pass the value Apple
into the function it will return the string "An apple a day keeps the doctor away"
.
Tagged Unions
Union Types can actually be more than simple enumerations – they can carry additional data. This is achieved with tagged unions. The following example defines a union type Shape
with two possible shapes:
-- A record definition. We had a look at records in the previous episode.
type alias Point =
{ x : Float
, y : Float
}
-- the tagged union Shape
type Shape
= Circle Point Float
| Rectangle Point Point
Each kind of Shape
defines different data that can be attached to it. A Circle
can hold a Point
(its center) and its radius (represented as a Float
). The Rectangle
in contrast has two Point
s attached to it, representing the upper left and the lower right corner. Keep in mind that the number of parameters and their types can be different for each member of a tagged union. You can also mix tagged union types with simple values (that do not have additional data).
Here is an example where you can see a tagged union in action:
import Html exposing (..)
type alias Point =
{ x : Float
, y : Float
}
type Shape
= Circle Point Float
| Rectangle Point Point
area : Shape -> Float
area shape =
case shape of
Circle center radius ->
pi * radius ^ 2
Rectangle corner1 corner2 ->
abs (corner1.x - corner2.x) * abs (corner1.y - corner2.y)
main : Html
main =
let
circle =
Circle { x = 2.3, y = 1.4 } 3.1
rectangle =
Rectangle { x = 0.5, y = 1.4 } { x = 3.5, y = 5.2 }
in
ul
[]
[ li [] [ area circle |> toString |> text ]
, li [] [ area rectangle |> toString |> text ]
]
The interesting part is the area
function. We use a case statement to calculate the area of a geometrical shape, which requires a different formula depending on the kind of shape. We also use the case statement to destructure the tagged union values, that is, to assign an identifier to the values inside the tagged union members. For example, the line
Circle center radius ->
enables us to access the Float
attached to the Circle
and use it in our calculation by assigning the identifier radius
to it. Since we do not use the center
value at all (it is not relevant for calculating the area), we also use the underscore wildcard (_
) which basically translates to "ignore this value, we do not need it here":
Circle _ radius ->
That’s about it on union types and tagged unions, so this concludes the tenth episode of this blog post series on Elm. Stay tuned for the next episode!
More articles
fromBastian Krol
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
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.
Blog author
Bastian Krol
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.