0 | module Control.Category.Monoidal
2 | import Control.Category.Core
3 | import Control.Category.Functor
4 | import Data.Morphisms
7 | import Data.List.Quantifiers
8 | import Data.Singleton
32 | interface (Category cat,
CatEndoBifunctor cat ten) =>
33 | Monoidal (0 cat : Hom obj) (ten : obj -> obj -> obj) (i : obj) | cat,ten where
34 | constructor MkMonoidal
36 | assoc : {a,b,c : _} -> cat ((a `ten` b) `ten` c) (a `ten` (b `ten` c))
38 | assoc' : {a,b,c : _} -> cat (a `ten` (b `ten` c)) ((a `ten` b) `ten` c)
41 | unitl : {a : _} -> cat (i `ten` a) a
43 | unitl' : {a : _} -> cat a (i `ten` a)
46 | unitr : {a : _} -> cat (a `ten` i) a
48 | unitr' : {a : _} -> cat a (a `ten` i)
57 | PreMonoidal : (cat : Hom obj) -> (ten : obj -> obj -> obj) -> (i : obj) -> Type
58 | PreMonoidal = Monoidal
69 | TenSeq : (ten : obj -> obj -> obj) -> (i : obj) -> List obj -> obj
72 | TenSeq ten i (o :: os@(_ :: _)) = o `ten` TenSeq ten i os
77 | splitAssoc : Monoidal cat ten i => {xs,ys : _} ->
78 | cat (TenSeq ten i (xs ++ ys)) (TenSeq ten i xs `ten` TenSeq ten i ys)
79 | splitAssoc @{c@(MkMonoidal {})} {xs=[]} = unitl'
80 | splitAssoc @{c@(MkMonoidal {})} {xs=[_],ys=[]} = unitr'
81 | splitAssoc @{c@(MkMonoidal {})} {xs=[_],ys=_::_} = id
82 | splitAssoc @{c@(MkMonoidal {})} {xs=[_,_],ys=_::_} = assoc'
83 | splitAssoc @{c@(MkMonoidal {})} {xs=_::_::_} = assoc' . mapr' splitAssoc
87 | mergeAssoc : Monoidal cat ten i => {xs,ys : _} ->
88 | cat (TenSeq ten i xs `ten` TenSeq ten i ys) (TenSeq ten i (xs ++ ys))
89 | mergeAssoc @{c@(MkMonoidal {})} {xs=[]} = unitl
90 | mergeAssoc @{c@(MkMonoidal {})} {xs=[_],ys=[]} = unitr
91 | mergeAssoc @{c@(MkMonoidal {})} {xs=[_],ys=_::_} = id
92 | mergeAssoc @{c@(MkMonoidal {})} {xs=[_,_],ys=_::_} = assoc
93 | mergeAssoc @{c@(MkMonoidal {})} {xs=_::_::_} = mapr' mergeAssoc . assoc
97 | applyAssoc : Monoidal cat ten i => {xs,ys,ys',zs : _} ->
98 | cat (TenSeq ten i ys) (TenSeq ten i ys') ->
99 | cat (TenSeq ten i (xs ++ ys ++ zs)) (TenSeq ten i (xs ++ ys' ++ zs))
100 | applyAssoc @{c@(MkMonoidal {})} f =
101 | mergeAssoc . mapr' (mergeAssoc . mapl' f . splitAssoc) . splitAssoc
115 | [MorFromTensor] {ten,i : _} -> Tensor ten i => Monoidal Morphism ten i
116 | using CatBifunctor.MorFromBifunctor where
118 | assoc' = Mor assocl
119 | unitl = Mor unitl.leftToRight
120 | unitl' = Mor unitl.rightToLeft
121 | unitr = Mor unitr.leftToRight
122 | unitr' = Mor unitr.rightToLeft
127 | [FuncFromTensor] {ten,i : _} -> Tensor ten i => Monoidal (~~>) ten i
128 | using Category.Function CatBifunctor.FuncFromBifunctor where
129 | assoc = Tensor.assocr
130 | assoc' = Tensor.assocl
131 | unitl = Tensor.unitl.leftToRight
132 | unitl' = Tensor.unitl.rightToLeft
133 | unitr = Tensor.unitr.leftToRight
134 | unitr' = Tensor.unitr.rightToLeft
143 | [KleisliFromTensor] {ten,i : _} ->(Tensor ten i, Bitraversable ten, Monad m) =>
144 | Monoidal (Kleislimorphism m) ten i using KleisliFromBitraversable where
145 | assoc = Kleisli $
Prelude.pure . assocr
146 | assoc' = Kleisli $
Prelude.pure . assocl
147 | unitl = Kleisli $
Prelude.pure . unitl.leftToRight
148 | unitl' = Kleisli $
Prelude.pure . unitl.rightToLeft
149 | unitr = Kleisli $
Prelude.pure . unitr.leftToRight
150 | unitr' = Kleisli $
Prelude.pure . unitr.rightToLeft
154 | FuncPair : Monoidal (~~>) Pair ()
155 | FuncPair = FuncFromTensor
158 | FuncEither : Monoidal (~~>) Either Void
159 | FuncEither = FuncFromTensor
162 | public export %hint
163 | MonoidalMorPair : Monoidal Morphism Pair ()
164 | MonoidalMorPair = MorFromTensor
166 | public export %hint
167 | MonoidalMorEither : Monoidal Morphism Either Void
168 | MonoidalMorEither = MorFromTensor
171 | public export %hint
172 | MonoidalKleisliPair : Monad m => PreMonoidal (Kleislimorphism m) Pair ()
173 | MonoidalKleisliPair = KleisliFromTensor
175 | public export %hint
176 | MonoidalKleisliEither : Monad m => Monoidal (Kleislimorphism m) Either Void
177 | MonoidalKleisliEither = KleisliFromTensor
182 | pairToHList : {ts : _} -> TenSeq Pair () ts -> HList ts
183 | pairToHList {ts=[]} () = []
184 | pairToHList {ts=[_]} x = [x]
185 | pairToHList {ts=_::_::_} (x,y) = x :: pairToHList y
188 | pairFromHList : HList ts -> TenSeq Pair () ts
189 | pairFromHList [] = ()
190 | pairFromHList [x] = x
191 | pairFromHList (x :: xs@(_ :: _)) = (x, pairFromHList xs)