Why There's No Need For MultiCase Matching in Elm
As a beginner developer with Elm, I quickly ended up both loving the union types and the _
operator, but found the absence of MultiCase matching a tad bit irritating until... I saw the light!
TL;DR?
Use the following pattern whenever you have some behavior shared by several constructors of your union types and stay away from the _
operator!
The problem with single case matching
Let's say I want to create task tracking software. I might end up with this Item
type to describe my model:
As you can guess, many operations are going to require the same treatment for most kind of Item
: assigning the item to somebody, changing the start or end date, adding/editing a description, etc. However, there will be some that will differ.
How can we deal with that?
underscore matching
Using the When I encountered this problem, my first idea was to use the _
to match all of the kinds of Item
that didn't require a specific treatment for any given case ... of
.
There are two main problems with that approach: we can't get the properties and it introduces potential BUGS, meaning problems and unexpected behavior that won't be caught by the compiler.
First, let's see how it looks:
Let's take back the Item
example and pretend that we want to create a new kind of Item
: milestone.
Let's say milestones do not have a start date but are just used as deadlines. Say my app is pretty developed and I am doing a lot of things on my Item
and use underscore matching a lot. By adding a new kind of Item
in my union type, I'd expect the compiler to throw a bunch of errors directly in my face.
However, this will not happen in that case: my new kind Milestone
would already be matched by the _
, so there won't be anything wrong that will be caught by the compiler. Yet I probably don' t want my Milestone
items to be dealt with like any other items, so I would have to look up any _
and make sure that I adapt the code manually.
The replacement
Use let … in
! (or make another helper function). It really is as simple as that. Instead of making MultiCase matching, put the common treatment in a function within the let ... in
or put it outside if the treatment is consequent and use it afterwards:
And voilà! It sounds pretty stupid, but I hope it helps!
Here is a small "project" showing this… nothing fancy, only one message and one button.