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).
Read next Measuring and visualizing GenStage/Flow with Gnuplot