Hi,
Tagged union types (now called ‘custom types’) are a great feature of Elm. Coming from languages that do not have them, we generally get a nice warm fuzzy aha moment when we first grok them.
I like how they fill out a missing dimension in data modelling, compared with languages that only support records.
-
A record type is a ‘product’; an instance of a record is a member of the set defined by the cross product of the sets defined by each of its fields.
-
A union type is a ‘sum’; an instance of a union type is a member of the set defined by taking the union of the sets defined by each of its constructors. That gives you a new angle on data modelling that is not so well expressed in some other languages and better enables choices to be encoded.
‘sum’ and ‘product’ form a natural pair of operators to work with; sometimes we combine things together into groupings that naturally align together as a record; sometimes we make choices between models to represent different possible beliefs about the state of the world that our application represents. Sum and product also follow similar rules to their mathematical counterparts, with multiplication distributing over addition and so on.
(there are other set operators that can be interesting to consider too - many of them find a natural home in SQL)
Often we need to interact with languages that do not directly support tagged union types. But the concept is so powerful, I am interested to see how they look when mapped to some frequently used languages that we might interact with when writing Elm applications.
Here is a simple example in Elm, that is not parameterized, has no functions in it, and is not recursive. Its from a content model I am working with that is fetched from a back-end:
type Content
= Text { uuid : String , title : String }
| Markdown { uuid : String , markdown : String }
| Figure { uuid : String , markdown : String , title : String , imageId : Maybe String }