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
18 | numIsMonoid : Num a => ComMonoid a
19 | numIsMonoid = MkComMonoid (+) 0
22 | listIsMonoid : ComMonoid (List a)
23 | listIsMonoid = MkComMonoid (++) []
26 | bagIsMonoid : ComMonoid (Bag a)
27 | bagIsMonoid = MkComMonoid (++) (MkBag [])
31 | pairIsMonoid : ComMonoid a => ComMonoid b => ComMonoid (a, b)
32 | pairIsMonoid @{MkComMonoid plusA neutralA} @{MkComMonoid plusB neutralB}
34 | (\(a, b), (a', b') => (plusA a a', plusB b b'))
35 | (neutralA, neutralB)
38 | sum : ComMonoid a => Bag a -> a
39 | sum @{mon} = foldr (plus mon) (neutral mon)
46 | namespace NotExposingType
50 | ComMonoid = (t : Type ** ComMonoid t)
53 | uSet : ComMonoid -> Type
58 | ComMonoidHomo : ComMonoid -> ComMonoid -> Type
59 | ComMonoidHomo (
t ** _) (
t' ** _)
= t -> t'
73 | fromGenerators : {0 a : Type} -> (mon : ComMonoid y) => (a -> y) ->
74 | ComMonoidHomo (
Bag a ** bagIsMonoid {a}) (
y ** mon)
75 | fromGenerators h = sum . map h
81 | scale : ComMonoid a => Nat -> a -> a
82 | scale @{mon} 0 a = neutral mon
83 | scale @{mon} (S k) a = plus mon a (scale k a)