16-Dec

Elm

# A Bunch of Nothing

One of the great advantages of Elm is its strong runtime guarantees, and one important technique it uses to achieve this is using data types such as `Maybe` and `Result` to handle errors, instead of having values like `null` or `undefined` in the language. These structures are very nice to work with, but if you don't know the tools at your disposal, they can be tricky.

·

By Gaute Berge

·

December 16, 2020

Suppose you have some data such as:

``````data : List String
data = ["1", "17", "a87", "34", "3b7"]``````

This was supposed to be a list of integers, but for whatever reason whoever provided you with this data also left in a bunch of garbage like `"a87"`. You're only interested in the strings that are valid integers, and you also want to work with them as integers, not strings. Let's start writing our `convert` function.

We can convert strings to integers with the function

``String.toInt : String -> Maybe Int``

and we can use our old friend `List.map` to apply the conversion to all the elements in the list:

``````List.map String.toInt data
-- [Just 1, Just 17, Nothing, Just 34, Nothing]``````

Now we have our integers, wrapped in `Just`, so all we have to do now is to remove the values that are `Nothing`.

"I know this one! That's `List.filter`, right?", you might have said prior to learning the lesson that I am getting to in this post. Let's try.

``List.filter isJust (List.map String.toInt data)``

There are two problems with this solution:

First of all, `isJust` is not provided by the core library. We could get it from `elm-community/maybe-extra`, or we could save ourselves a dependency and just define it ourselves:

``````isJust maybe =
case maybe of
Just _ -> True
Nothing -> False``````

Now we can see if it works:

``````List.filter isJust (List.map String.toInt data)
-- [Just 1, Just 17, Just 34]``````

We got rid of the bad entries, but we have another problem. All our values are still wrapped up in `Just`! Each time you would want to use these values, you would have to handle the case of it being `Nothing`, even though we just made sure all the `Nothing`-values are gone. We have now introduced an impossible state 💀. What we really want is a function with the type

``convert : List String -> List Int``

as opposed to what we had, which was:

``convert : List String -> List (Maybe Int)``

Fortunately the solution is very simple! The core library provides the function which does exactly this:

``List.filterMap : (a -> Maybe b) -> List a -> List b``

`List.filterMap` takes a function that produces a `Maybe`, and applies that functions to all the elements of a list while unpacking the `Just`-values, and removing the `Nothing`-values.

Our final convert function can then be defined simply as:

``````convert = List.filterMap String.toInt

convert data
-- [1, 17, 34]``````

## Conclusion

Error handling in Elm is easy as long as you you have the right functions in your tool belt. With `List.filterMap` and a few more you will be able to handle anything 🎉