Elm Language Constructing Types


Example

The type alias keyword combination gives a new name for a type, but the type keyword in isolation declares a new type. Let's examine one of the most fundamental of these types: Maybe

type Maybe a
    = Just a
    | Nothing

The first thing to note is that the Maybe type is declared with a type variable of a. The second thing to note is the pipe character, |, which signifies "or". In other words, something of type Maybe a is either Just a or Nothing.

When you write the above code, Just and Nothing come into scope as value-constructors, and Maybe comes into scope as a type-constructor. These are their signatures:

Just : a -> Maybe a

Nothing : Maybe a

Maybe : a -> Maybe a -- this can only be used in type signatures

Because of the type variable a, any type can be "wrapped inside" of the Maybe type. So, Maybe Int, Maybe (List String), or Maybe (Maybe (List Html)), are all valid types. When destructuring any type value with a case expression, you must account for each possible instantiation of that type. In the case of a value of type Maybe a, you have to account for both the Just a case, and the Nothing case:

thing : Maybe Int
thing = 
    Just 3

blah : Int
blah =
    case thing of
        Just n -> 
            n

        Nothing ->
            42

-- blah = 3

Try writing the above code without the Nothing clause in the case expression: it won't compile. This is what makes the Maybe type-constructor a great pattern for expressing values that may not exist, as it forces you to handle the logic of when the value is Nothing.