The Maybe type is the solution in the Elm language for optional values.
It is thus present in type signatures of a wide number of core Elm functions and understanding it is crucial.
The Maybe type is defined as follows:
type Maybe a = Nothing | Just a
This is known as a "custom type" definition in Elm terminology.
Custom types are introduced in details in another concept of this track but we won't need it to understand specifically Maybe.
The a in Maybe a and Just a represents a type variable, meaning it can be any type, such as Int, Bool or String.
As such, a Maybe String is a variable that optionally holds a String, while a Maybe Int would optionally hold an Int.
name : Maybe String
name = Just "Matthieu"
age : Maybe Int
age = Just 29
The vertical bar | in the type definition of Maybe means "OR".
It indicates that a value of this type can either be Nothing OR be Just something of type a.
So imagine that the name and age were not filled by that person, we would have the following.
name : Maybe String
name = Nothing
age : Maybe Int
age = Nothing
Reading the content of a Maybe value is done via "pattern matching".
Pattern matching is also introduced in more details in another concept, so we just focus on how pattern matching a Maybe works.
-- This function returns "Hello, <name>!" if the name was provided.
-- Otherwise, it just says "Hello, World!".
sayHello : Maybe String -> String
sayHello maybeName =
case maybeName of
Nothing -> "Hello, World!"
Just someName -> "Hello, " ++ someName ++ "!"
sayHello (Just "Matthieu")
--> "Hello, Matthieu!"
sayHello Nothing
--> "Hello, World!"
Every time you use a Maybe value, the Elm compiler will check that your code handles all possibilities so you can never pattern match a Maybe and only handle the case where there is a Just someValue.
This may seem annoying at first, but it is one of the greatest strengths of the Elm language.
This will prevent hundreds of bugs and makes compiler-guided refactoring a fearless and rewarding experience.
Maybe
There are also a number of useful functions in the Maybe module to manipulate Maybe types.
sayHelloAgain : Maybe String -> String
sayHelloAgain name = "Hello, " ++ Maybe.withDefault "World" name ++ "!"
capitalizeName : Maybe String -> Maybe String
capitalizeName name = Maybe.map String.toUpper name
capitalizeName matthieu
--> Just "MATTHIEU"
capitalizeName anon
--> Nothing