title: Idiomatic way to represent sum type (Either a b) in Clojure
body: <p><em>Edited. My question now is: what idiomatic Clojure constructs are usually used instead of sum types in statically types languages? Consensus so far: use protocols if behaviour can be unified, use tagged pairs/maps otherwise, put necessary asserts in pre- and post-conditions.</em></p>
  
  <p>Clojure provides many ways to express <em>product types</em>: vectors, maps, records..., but how do you represent <a href="https://en.wikipedia.org/wiki/Sum_type"><em>sum types</em></a>, also known as tagged unions and variant records? Something like <code>Either a b</code> in Haskell or <code>Either[+A, +B]</code> in Scala.</p>
  
  <p>The first thing which comes to my mind is a map with a special tag: <code>{:tag :left :value a}</code>, but then all the code is going to be polluted with conditionals on <code>(:tag value)</code> and handling special cases if it's not there... What I'd like to ensure, is that <code>:tag</code> 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 <code>nil</code>, and there is an easy way to see that I took care of all cases in the code.</p>
  
  <p><strike>I can think of a macro in the lines of <code>defrecord</code>, but for the sum types:</p>
  
  <pre><code>; it creates a special record type and some helper functions
  (defvariant Either
     left Foo
     right :bar)
  ; user.Either
  
  (def x (left (Foo. "foo")))   ;; factory functions for every variant
  ; #user.Either{:variant :left :value #user.Foo{:name "foo"}}
  (def y (right (Foo. "bar")))  ;; factory functions check types
  ; SomeException...
  (def y (right ^{:type :bar} ()))
  ; #user.Either{:variant :right :value ()}
  
  (variants x) ;; list of all possible options is intrinsic to the value
  ; [:left :right]
  </code></pre>
  
  <p>Does a thing like this already exist?</strike> (<em>Answered: no</em>).</p>