Coproducts give the choice of one out of two possible types, once given a value of
a coproduct we need to pattern-match to find out what value is actually carried.
Here we define the coproduct type with the familiar (+) operator that symbolises
the sum. Each inhabitant of the coproduct uses a left (<+) prefix operator (see section \ref{unicode-and-operators}) or a right (+>)
prefix operator to distinguish what value is being carried.
Definition
Coproducts are given by two constructors, one for the left choice (<+) and one for the right choice (+>)
data (+) : Type -> Type -> Type where ||| Left choice (<+) : a -> a + b ||| Right choice (+>) : b -> a + b
Proposition
Given two maps a→c and b→c we can eliminate a coproduct a+b into a value c. This is the eliminator for coproducts, or equivalently, the universal property of coproducts.
choice : (a -> c) -> (b -> c) -> a + b -> cchoice f g (<+ x) = f xchoice f g (+> x) = g x
Proposition
The diagonal operator eliminates a coproduct if both sides are the same type.
dia : a + a -> adia (<+ x) = xdia (+> x) = x
Proposition
Coproducts form a bifunctor on types.
Bifunctor (+) where bimap f g (<+ x) = <+ (f x) bimap f g (+> x) = +> (g x)
Proposition
Void is the neutral for the coproduct.
public exportgetRight : Void + a -> agetRight (<+ x) = void xgetRight (+> x) = xpublic exportgetLeft : a + Void -> agetLeft (<+ x) = xgetLeft (+> x) = void x
exportdistribF : Functor f => f a + f b -> f (a + b)distribF (<+ x) = map (<+) xdistribF (+> x) = map (+>) x
public exportdchoice : {0 a, b : Type} -> {0 c : a + b -> Type} -> ((x : a) -> c (<+ x)) -> ((x : b) -> c (+> x)) -> (x : a + b) -> c xdchoice f g (<+ x) = f xdchoice f g (+> x) = g x