0 | module Data.Coproduct
2 | import Control.Function
6 | import public Data.Ops
12 | data (+) : Type -> Type -> Type where
20 | choice : (a -> c) -> (b -> c) -> a + b -> c
21 | choice f g (<+ x) = f x
22 | choice f g (+> x) = g x
25 | dchoice : {0 a, b : Type} -> {0 m : a + b -> Type} ->
26 | (l : (x : a) -> m (<+ x)) ->
27 | (r : (x : b) -> m (+> x)) ->
29 | dchoice l r (<+ x) = l x
30 | dchoice l r (+> x) = r x
38 | assocL : (a + b) + c -> a + (b + c)
39 | assocL (<+ (<+ x)) = <+ x
40 | assocL (<+ (+> x)) = +> (<+ x)
41 | assocL (+> x) = +> (+> x)
44 | assocR : a + (b + c) -> (a + b) + c
45 | assocR (<+ x) = <+ (<+ x)
46 | assocR (+> (<+ x)) = <+ (+> x)
47 | assocR (+> (+> x)) = +> x
52 | bimap f g (<+ x) = <+ (f x)
53 | bimap f g (+> x) = +> (g x)
56 | Functor (Coproduct.(+) a) where
60 | Applicative (Coproduct.(+) a) where
62 | (<*>) (<+ e) _ = <+ e
63 | (<*>) (+> f) (<+ x) = <+ x
64 | (<*>) (+> f) (+> x) = +> f x
67 | Monad (Coproduct.(+) a) where
72 | Alternative (Coproduct.(+) Unit) where
75 | (<|>) (+> x) _ = +> x
78 | Show a => Show b => Show (a + b) where
79 | show (<+ l) = show l
80 | show (+> r) = show r
84 | Injective (<+) where
85 | injective Refl = Refl
89 | Injective (+>) where
90 | injective Refl = Refl
94 | Sum : (n : Nat) -> (a : Type) -> Type
97 | Sum (S x) y = y + Sum x y
100 | SumList : List Type -> Type
102 | SumList (x :: xs) = x + SumList xs
105 | match : {a : _} -> SumList a -> SumList b -> SumList (a ++ b)
106 | match {a = []} x y = y
107 | match {a = (ty :: xs)} (<+ x) y = <+ x
108 | match {a = (ty :: xs)} (+> x) y = +> match x y
111 | split : {a : _} -> SumList (a ++ b) -> SumList a + SumList b
112 | split {a = []} x = +> x
113 | split {a = (y :: xs)} (<+ x) = <+ <+ x
114 | split {a = (y :: xs)} (+> x) = case split x of
115 | (<+ z) => <+ (+> z)
121 | Selector : Nat -> Type -> Type
122 | Selector n a = (Fin n, a)
126 | finToSum : {0 n : Nat} -> Selector n a -> Sum n a
127 | finToSum {n = S Z} (FZ, y) = y
128 | finToSum {n = S Z} (FS x, y) = y
132 | diagonal : (n : Nat) -> Sum n a -> a
133 | diagonal 0 x = void x
134 | diagonal (S 0) x = x
135 | diagonal (S (S k)) (<+ x) = x
136 | diagonal (S (S k)) (+> x) = diagonal (S k) x
140 | sumToSelector : {n : Nat} -> Sum n a -> (Fin n, a)
141 | sumToSelector x {n = Z} = void x
142 | sumToSelector x {n = (S Z)} = (FZ, x)
143 | sumToSelector (<+ x) {n = (S (S k))} = (FZ, x)
144 | sumToSelector (+> x) {n = (S (S k))} = mapFst FS $
sumToSelector {n = S k} x
148 | ChoiceN : (n : Nat) -> (ty : a -> Type) -> Sum n a -> Type
149 | ChoiceN Z ty _ = Void
150 | ChoiceN (S Z) ty v = ty v
151 | ChoiceN (S (S n)) ty idx =
152 | Coproduct.choice (ty) (\x => ChoiceN (S n) ty x) idx
155 | diaChoice : {n : Nat} -> {0 b : Type} ->
156 | (c : Sum n a) -> b -> ChoiceN n {a} (const b) c
157 | diaChoice {n = 0} c x = c
158 | diaChoice {n = (S 0)} c x = x
159 | diaChoice {n = (S (S k))} (<+ y) x = x
160 | diaChoice {n = (S (S k))} (+> y) x = diaChoice y x
163 | fromMaybe : Maybe a -> () + a
164 | fromMaybe = maybe (<+ ()) (+>)
167 | swap : a + b -> b + a
173 | alwaysLeft : a + Void -> a
174 | alwaysLeft (<+ x) = x
178 | alwaysRight : Void + b -> b
179 | alwaysRight (+> x) = x