Understanding elm union types

elm, union-types

Solution

When defining a union type, you list all the ways to construct a value of that type. In its simplest form, that definition looks like this:

type Visibility 
  = All 
  | Active 
  | Completed

As you've surmised, this declares the type `Visibility` and defines three values, all of type `Visibility`. The only way to construct a value of type `Visibility` is to use one of these three options. Because of that, we often call them "constructors."

Here is a slightly more complicated union type definition:

type TrainStatus
  = OnTime
  | Delayed Int

As you would expect, this defines two new "constructors," `OnTime` and `Delayed`. But look at their types:

OnTime  : TrainStatus
Delayed : Int -> TrainStatus

The `OnTime` constructor takes zero arguments, and so is simply a value; it is already a `TrainStatus`. But `Delayed` is declared as a one-argument constructor: it is a function that creates a new `TrainStatus` out of an `Int`. As such, `Delayed 5`, `Delayed 10`, and `Delayed 100` are all valid `TrainStatus` values. (We can interpret them as "delayed by 5 minutes" or something similar.)

A constructor can take multiple arguments; for instance, if we'd like to include, as a String, a reason for a delay:

type TrainStatus
  = OnTime
  | Delayed Int String

ts : TrainStatus
ts = Delayed 20 "The conductor took a short nap."

which defines `Delayed : Int -> String -> TrainStatus`.

If you're given a `TrainStatus`, you can extract the `Int` and `String` inside of it using pattern matching:

case ts of
  OnTime ->
    "Your train is on time!"

  Delayed minutes reason ->
    "Your train has been delayed by " ++ toString minutes ++ " because " ++ reason

Problem

I am having some troubles wrapping my head around union types in elm. I understand the simple use case like ``` type Visibility = All | Active | Completed ``` So that means that the value of Visiblity can be All, Active or Completed. So far so good. Where i get confused however is ``` type Msg = OnFetchMails (WebData (List Mail)) | OnFetchSmss (WebData (List SMS)) ``` How should i interpret this? Does it mean Msg can be of the type function OnFetchMails that takes a type function WebData that takes a list of mail? Or how should i interpret this? I don't think that `(WebData (List Mail))` is the payload? Funny enough i can get it to work without understanding it

Original source