Let’s say we have the weekdays being represented in numbers between 0
and 6
and we want to convert those numbers to strings (0
= Sunday, 1
= Monday, etc.). We can use an if
expression to do that. Add the following function definition right above main
in Playground.elm
.
Now let’s render Friday
on a browser by calling the weekday
function from main
.
Refresh the page at http://localhost:8000/src/Playground.elm
and you should see Friday
. As it stands right now, the weekday
function looks a bit superfluous. It does nothing more than a number comparison in each conditional branch. Can we express it more succinctly? Let’s try using a case
expression.
Ah! Much better!
Case Expression Syntax
case
works by matching an expression to a pattern. When a match is found, it evaluates the expression to the right of ->
and returns whatever value is produced.
- Pattern Matching
- Pattern matching is the act of checking one or more inputs against a pre-defined pattern and seeing if they match. We will explore pattern matching in much more detail in chapter 4.
The expression after the keyword case
can be anything from a simple value to a complex computation including function applications. For example, if we want to generate a hashtag for each day, we can write another function that takes a string value returned by the weekday
function and matches it against a hashtag. Add the following function definition right above main
in Playground.elm
.
Now call the hashtag
function instead of weekday
from main
.
Refresh the page at http://localhost:8000/src/Playground.elm
and you should see #FlashbackFriday
. You might be tempted to line each arrow (->
) up when writing a case
expression like this:
The Elm style guide tells us not to do that. Although this arrangement is easier on the eye, it takes aways the ease of modification. Let’s say we need to add another day with a long name to the list of patterns. Now we need to move all the arrows. But if we arrange the code as suggested by the style guide, then it becomes much easier to modify. Although elm-format
automatically reformats our code to follow the style guide, I wanted to point it out here so that you understand why a case
expression in Elm is formatted like that.
Catch All Pattern
Notice how we used _
in both examples above as the last pattern? Without it, Elm will throw an error. Go ahead and remove the line that contains _
from the weekday
function and refresh the page at http://localhost:8000/src/Playground.elm
. You should see the following error.
We have to account for every single value an expression can have. Since dayInNumber
holds an integer whose range is quite big, it’s not feasible to list all those options in our code. The _
character works as a catch-all-pattern. Because of this, it’s important to place the most specific pattern at the top and the least specific at the bottom. For example, if we move _
to the top, the weekday
function will always return "Unknown day"
no matter what number we pass in. Add the catch-all-pattern back to the weekday
function.
If vs Case Expression
Does this mean all if
expressions can be replaced with case
? Not necessarily. A case
expression works by matching a pattern, whereas an if
expression checks whether a condition is true or not. For example, the following code doesn’t really have a pattern.
If we attempt to re-write it with a case
expression, we will get an error. Add the following function definition right above main
in Playground.elm
.
If you refresh the page at http://localhost:8000/src/Playground.elm
, you should see the following error.
The reason why Elm is throwing an error is because there is no pattern to match here. All we have is a couple of disparate conditions. More importantly, the part before ->
has to be a pattern. It can’t be any expression. Here we are trying to compare the given velocity and speed with some number using an expression.
Go ahead and remove the escapeEarthWithCase
function from Playground.elm
and refresh the page at http://localhost:8000/src/Playground.elm
to make sure there are no errors.
To summarize, if we have disparate conditions to check then if
expression is a good fit. Whereas if we need to match an expression to a pattern, a case
expression is the way to go.