0 | module Data.ComMonoid
2 | import public Data.Num
3 | import public Data.Bag
8 | record ComMonoid (a : Type) where
9 | constructor MkComMonoid
18 | numIsMonoid : Num a => ComMonoid a
19 | numIsMonoid = MkComMonoid (+) 0
23 | listIsMonoid : ComMonoid (List a)
24 | listIsMonoid = MkComMonoid (++) []
27 | bagIsMonoid : ComMonoid (Bag a)
28 | bagIsMonoid = MkComMonoid (++) (MkBag [])
32 | pairIsMonoid : ComMonoid a => ComMonoid b => ComMonoid (a, b)
33 | pairIsMonoid @{MkComMonoid plusA neutralA} @{MkComMonoid plusB neutralB}
35 | (\(a, b), (a', b') => (plusA a a', plusB b b'))
36 | (neutralA, neutralB)
39 | sum : ComMonoid a => Bag a -> a
40 | sum @{mon} = foldr (plus mon) (neutral mon)
42 | namespace NotExposingType
46 | ComMonoid = (t : Type ** ComMonoid t)
50 | uSet : ComMonoid -> Type
56 | ComMonoidHomo : ComMonoid -> ComMonoid -> Type
57 | ComMonoidHomo m n = uSet m -> uSet n
62 | functionIsMonoid : {0 a : Type} -> ComMonoid b -> ComMonoid (a -> b)
63 | functionIsMonoid m = MkComMonoid
64 | (\f, g => \x => plus m (f x) (g x))
70 | natMon = (
Nat ** numIsMonoid)
73 | Free : Type -> ComMonoid
74 | Free a = (
Bag a ** bagIsMonoid)
80 | fromGenerators : {0 a : Type} -> {y : ComMonoid} ->
82 | ComMonoidHomo (Free a) y
83 | fromGenerators f b = sum @{snd y} (f <$> b)
89 | scale : ComMonoid a => Nat -> a -> a
90 | scale @{mon} 0 a = neutral mon
91 | scale @{mon} (S k) a = plus mon a (scale k a)