0 | module Data.ComMonoid
2 | import public Data.Num
3 | import public Data.Bag
5 | %hide Prelude.Semigroup
11 | record ComMonoid (a : Type) where
12 | constructor MkComMonoid
21 | numIsMonoid : Num a => ComMonoid a
22 | numIsMonoid = MkComMonoid (+) 0
26 | listIsMonoid : ComMonoid (List a)
27 | listIsMonoid = MkComMonoid (++) []
30 | bagIsMonoid : ComMonoid (Bag a)
31 | bagIsMonoid = MkComMonoid (++) (MkBag [])
35 | pairIsMonoid : ComMonoid a => ComMonoid b => ComMonoid (a, b)
36 | pairIsMonoid @{MkComMonoid plusA neutralA} @{MkComMonoid plusB neutralB}
38 | (\(a, b), (a', b') => (plusA a a', plusB b b'))
39 | (neutralA, neutralB)
42 | sum : ComMonoid a => Bag a -> a
43 | sum @{mon} = foldr (plus mon) (neutral mon)
45 | namespace NotExposingType
49 | ComMonoid = (t : Type ** ComMonoid t)
53 | uSet : ComMonoid -> Type
59 | ComMonoidHomo : ComMonoid -> ComMonoid -> Type
60 | ComMonoidHomo m n = uSet m -> uSet n
65 | functionIsMonoid : {0 a : Type} -> ComMonoid b -> ComMonoid (a -> b)
66 | functionIsMonoid m = MkComMonoid
67 | (\f, g => \x => plus m (f x) (g x))
73 | natMon = (
Nat ** numIsMonoid)
76 | Free : Type -> ComMonoid
77 | Free a = (
Bag a ** bagIsMonoid)
83 | fromGenerators : {0 a : Type} -> {y : ComMonoid} ->
85 | ComMonoidHomo (Free a) y
86 | fromGenerators f b = sum @{snd y} (f <$> b)
92 | scale : ComMonoid a => Nat -> a -> a
93 | scale @{mon} 0 a = neutral mon
94 | scale @{mon} (S k) a = plus mon a (scale k a)