Search code examples
elm

What happens under the hood when we define a type alias with a type variable in Elm


Suppose we define a type alias say Message as:

type alias Message a =
{ code : String
, body : a
}

And later define a function readMessage as:

readMessage : Message () -> String
readMessage message =
...

The above example is from Elm tutorial and book says:

This function takes Message with an empty body. This is not the same as any value, just an empty one.

Can someone please elaborate what exactly happens in above scenario and how compiler handles it.


Solution

  • Unless you really want to see the internal compiler representation of that, I think what's important here is the difference between any value and empty value.

    Message a is a parametrized type with 1 parameter. You can read it as a template, e.g. wherever lowercase a appears in the definition of the Message it will be substituted with the concrete type (String, Int, etc).

    So this is how function should look like if we want it to take a Message with String body:

    readMessage : Message String -> String
    readMessage message =
    

    What happens here is that the type of body field is no longer an a but a String (a is substituted with String):

    { code : String
    , body : String
    }
    

    The value of nothing (aka void or unit) in Elm is encoded as (). That's why a Message with empty body value looks like this:

    { code : String
    , body : ()
    }
    

    But when we simply don't care about the body value we can just take a Message with any value:

    readMessage : Message a -> String
    readMessage message =
    

    The lowercase a can be any lowercase string, we can make it more readable like this:

    readMessage : Message any -> String
    readMessage message =
    

    But then we cannot really read message body, because we don't know the type of it (so we don't know how to read it).

    Hope that helps.