Tips for Getting Started with Elixir & IEx Measuring and visualizing GenStage/Flow with Gnuplot

Discriminated unions (algebraic data types) in Elixir

Elixir already has product-type, tuples, which allow to aggregate several values in to one. But it lacks a sum-type, which allows to create a structure with a fixed set of values and guards all of them are handled. DiscUnion solves this.

With it, you can create a structure with a finite set of values, and have compile-time warnings if you try to use a wrong value or miss handling one case:

shape.ex:

defmodule Shape do
  use DiscUnion

  defunion Point
  | Circle in float()
  | Rectangle in any * any
end

solver.ex:

defmofule Solver do
  use Shape

  def calc_area(shape) do
    Shape.calc shape do
      Point in _        -> 0.0
      Circle in r       -> :math.pi * r * r
      Rectangle in w, h -> w*h
    end
  end
end

If there would be a typo in Rectangle in solver.ex or this line would be missed completely, app would not compile and UndefinedUnionCaseError or MissingUnionCaseError would be raised.

For more complete example see tennis kata example (which also creates a structure that does not allow creating invalid state of the game - thanks to using ADTs).