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
40 | bimap f g (<+ x) = <+ (f x)
41 | bimap f g (+> x) = +> (g x)
44 | Functor (Coproduct.(+) a) where
48 | Applicative (Coproduct.(+) a) where
50 | (<*>) (<+ e) _ = <+ e
51 | (<*>) (+> f) (<+ x) = <+ x
52 | (<*>) (+> f) (+> x) = +> f x
55 | Monad (Coproduct.(+) a) where
60 | Alternative (Coproduct.(+) Unit) where
63 | (<|>) (+> x) _ = +> x
66 | Show a => Show b => Show (a + b) where
67 | show (<+ l) = show l
68 | show (+> r) = show r
72 | Injective (<+) where
73 | injective Refl = Refl
77 | Injective (+>) where
78 | injective Refl = Refl
82 | Sum : (n : Nat) -> (a : Type) -> Type
85 | Sum (S x) y = y + Sum x y
88 | SumList : List Type -> Type
90 | SumList (x :: xs) = x + SumList xs
93 | match : {a : _} -> SumList a -> SumList b -> SumList (a ++ b)
94 | match {a = []} x y = y
95 | match {a = (ty :: xs)} (<+ x) y = <+ x
96 | match {a = (ty :: xs)} (+> x) y = +> match x y
99 | split : {a : _} -> SumList (a ++ b) -> SumList a + SumList b
100 | split {a = []} x = +> x
101 | split {a = (y :: xs)} (<+ x) = <+ <+ x
102 | split {a = (y :: xs)} (+> x) = case split x of
103 | (<+ z) => <+ (+> z)
109 | Selector : Nat -> Type -> Type
110 | Selector n a = (Fin n, a)
114 | finToSum : {0 n : Nat} -> Selector n a -> Sum n a
115 | finToSum {n = S Z} (FZ, y) = y
116 | finToSum {n = S Z} (FS x, y) = y
120 | diagonal : (n : Nat) -> Sum n a -> a
121 | diagonal 0 x = void x
122 | diagonal (S 0) x = x
123 | diagonal (S (S k)) (<+ x) = x
124 | diagonal (S (S k)) (+> x) = diagonal (S k) x
128 | sumToSelector : {n : Nat} -> Sum n a -> (Fin n, a)
129 | sumToSelector x {n = Z} = void x
130 | sumToSelector x {n = (S Z)} = (FZ, x)
131 | sumToSelector (<+ x) {n = (S (S k))} = (FZ, x)
132 | sumToSelector (+> x) {n = (S (S k))} = mapFst FS $
sumToSelector {n = S k} x
136 | ChoiceN : (n : Nat) -> (ty : a -> Type) -> Sum n a -> Type
137 | ChoiceN Z ty _ = Void
138 | ChoiceN (S Z) ty v = ty v
139 | ChoiceN (S (S n)) ty idx =
140 | Coproduct.choice (ty) (\x => ChoiceN (S n) ty x) idx
143 | diaChoice : {n : Nat} -> {0 b : Type} ->
144 | (c : Sum n a) -> b -> ChoiceN n {a} (const b) c
145 | diaChoice {n = 0} c x = c
146 | diaChoice {n = (S 0)} c x = x
147 | diaChoice {n = (S (S k))} (<+ y) x = x
148 | diaChoice {n = (S (S k))} (+> y) x = diaChoice y x
151 | fromMaybe : Maybe a -> () + a
152 | fromMaybe = maybe (<+ ()) (+>)
155 | swap : a + b -> b + a
161 | alwaysLeft : a + Void -> a
162 | alwaysLeft (<+ x) = x
166 | alwaysRight : Void + b -> b
167 | alwaysRight (+> x) = x