Idiomatic way to represent sum type (Either a b) in Clojure
Reference: Idiomatic way to represent sum type (Either a b) in Clojure
how do you represent sum types, also known as tagged unions and variant records? Something like
Either a b
in Haskell orEither[+A, +B]
in Scala.
Either
has two uses: to return a value of one of two types or to
return two values of the same type that should have different semantics
based on the tag.
The first use is only important when using a static type system.
Either
is basically the minimum solution possible given the
constraints of the Haskell type system. With a dynamic type system, you
can return values of any type you want. Either
is not needed.
The second use is significant but can be accomplished quite simply in two (or more) ways:
{:tag :left :value 123} {:tag :right :value "hello"}
{:left 123} {:right "hello"}
[:left 123] [:right "hello"]
What I'd like to ensure, is that :tag is always there, and it can take only one of the specified values, and corresponding value is consistently of the same type/behaviour and cannot be nil, and there is an easy way to see that I took care of all cases in the code.
If you would like to ensure this statically, Clojure is probably not your language. The reason is simple: expressions do not have types until runtime---until they return a value.
The reason a macro will not work is that at macro expansion time, you do not
have runtime values---and hence runtime types. You have compile-time constructs
like symbols, atoms, s-expressions, etc. You can eval
them, but using eval
is considered bad practice for a number of reasons.