Union types
Elchemy (exactly like Elm) uses Tagged union types What it means is basically you can define a type by adding a tag to an already existing value and the meaning of this tag is to inform about the context of that value.
For instance:
type Shape = Dot Int | Line Int Int | Triangle Int Int Int
What's important is that Dot, Line and Triangle are just tags, so they can't be used as a type name (in function signatures for example) The only purpose of these is to pattern match on them in constructs like case..of, let..in or in arguments
Elchemy represents tagged unions as tuples with a first element being an atom with snake_cased tag name, or - in case of just tags - as a single atom value.
For example our previously defined type would translate to:
@type shape :: { :dot, integer() } |
{ :line, integer(), integer() } |
{ :triangle, integer(), integer(), integer() }
But a type like this:
type Size = XS | S | M | L | XL
Would translate to:
@type size :: :xs | :s | :m | :l | :xl
Type Parameters
Types can also take type parameters like:
type Maybe x = Just x | Nothing
All type parameters will resolve to any() by Elchemy.
Types as constructors
A Type can be insinstantiated using a tag and values.
For example to instantiate Just Int
we would write Just 10
.
If you don't provide all of the parameters, Elchemy will recognize it and
translate it into a curried function, so that 'Just' instead turning into;
:just
turns into:
fn x1 -> {:just, x1} end