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.
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.