0 | module Control.Category.MonFunctor
  1 |
  2 | import Control.Category.Core
  3 | import Control.Category.Functor
  4 | import Control.Category.Monoidal
  5 | import Data.Morphisms
  6 |
  7 | %default total
  8 |
  9 | ------------------------------------------------------------
 10 | -- Interface
 11 | ------------------------------------------------------------
 12 |
 13 | ||| A lax monoidal functor from `cat` to `cat'`.
 14 | |||
 15 | ||| This is the interface-style definition of a lax monoidal functor.
 16 | ||| For the record-style definition, see `Control.Category.Records.LaxMonFunctorR`.
 17 | |||
 18 | ||| Laws:
 19 | ||| * `map assoc . fjoin . mapl fjoin = fjoin . mapr fjoin . assoc`
 20 | ||| * `map unitl . fjoin . mapl funit = unitl`
 21 | ||| * `map unitr . fjoin . mapr funit = unitr`
 22 | public export
 23 | interface CatFunctor cat cat' f => LaxMonFunctor
 24 |     (0 cat : Hom obj) (0 ten : obj -> obj -> obj) (0 i : obj)
 25 |     (0 cat' : Hom obj') (0 ten' : obj' -> obj' -> obj') (0 i' : obj')
 26 |     (0 f : obj -> obj') | cat,ten,cat',ten',f where
 27 |   constructor MkLaxMonFunctor
 28 |   ||| The lax monoidal functor action on the tensor product.
 29 |   fjoin : {a,b : _} -> cat' (f a `ten'` f b) (f (a `ten` b))
 30 |   ||| The lax monoidal functor action on the unit object.
 31 |   funit : cat' i' (f i)
 32 |
 33 | ||| A type synonym for a lax monoidal endofunctor, a lax monoidal
 34 | ||| functor from a monoidal category to itself.
 35 | |||
 36 | ||| This is the interface-style definition of a lax monoidal
 37 | ||| endofunctor. For the record-style definition, see
 38 | ||| `Control.Category.Records.LaxMonEndofunctorR`.
 39 | public export %inline
 40 | LaxMonEndofunctor : (cat : Hom obj) -> (ten : obj -> obj -> obj) -> (i : obj) -> (f : obj -> obj) -> Type
 41 | LaxMonEndofunctor cat ten i = LaxMonFunctor cat ten i cat ten i
 42 |
 43 |
 44 | ||| A (strong) monoidal functor from `cat` to `cat'`.
 45 | |||
 46 | ||| This is the interface-style definition of a monoidal functor. For
 47 | ||| the record-style definition, see `Control.Category.Records.MonFunctorR`.
 48 | |||
 49 | ||| Laws:
 50 | ||| * `funit . funit' = funit' . funit = id`
 51 | ||| * `fjoin . fjoin' = fjoin' . fjoin = id`
 52 | public export
 53 | interface LaxMonFunctor cat ten i cat' ten' i' f => MonFunctor
 54 |     (0 cat : Hom obj) (0 ten : obj -> obj -> obj) (0 i : obj)
 55 |     (0 cat' : Hom obj') (0 ten' : obj' -> obj' -> obj') (0 i' : obj')
 56 |     (0 f : obj -> obj') | cat,ten,cat',ten',f where
 57 |   constructor MkMonFunctor
 58 |   ||| The inverse monoidal functor action on the tensor product.
 59 |   |||
 60 |   ||| This is the inverse of `fjoin`.
 61 |   fjoin' : {a,b : _} -> cat' (f (a `ten` b)) (f a `ten'` f b)
 62 |   ||| The inverse monoidal functor action on the unit object.
 63 |   |||
 64 |   ||| This is the inverse of `funit`.
 65 |   funit' : cat' (f i) i'
 66 |
 67 | ||| A type synonym for a monoidal endofunctor, a monoidal functor from
 68 | ||| a monoidal category to itself.
 69 | |||
 70 | ||| This is the interface-style definition of a monoidal endofunctor.
 71 | ||| For the record-style definition, see `Control.Category.Records.MonEndofunctorR`.
 72 | public export %inline
 73 | MonEndofunctor : (cat : Hom obj) -> (ten : obj -> obj -> obj) -> (i : obj) -> (f : obj -> obj) -> Type
 74 | MonEndofunctor cat ten i = MonFunctor cat ten i cat ten i
 75 |
 76 | ||| An endofunctor has *tensorial strength* if it is compatible with a
 77 | ||| monoidal category's tensor product. Generally, `cat` is a monoidal
 78 | ||| category with `ten` as its tensor product, though this is not
 79 | ||| enforced by the interface.
 80 | |||
 81 | ||| Note that while all Prelude functors have strength over `Pair`,
 82 | ||| this does not necessarily hold for other tensor products or in
 83 | ||| other categories.
 84 | |||
 85 | ||| This is the interface-style definition of a strong functor. For
 86 | ||| the record-style definition, see `Control.Category.Records.StrongFunctorR`.
 87 | |||
 88 | ||| Laws (when `cat` is a monoidal category):
 89 | ||| * `map unitl . strongl = unitl`
 90 | ||| * `map unitr . strongr = unitr`
 91 | ||| * `map assoc . strongl = strongl . mapr strongl . assoc`
 92 | ||| * `map assoc' . strongr = strongr . mapl strongr . assoc'`
 93 | ||| * `strongr . mapl strongl = strongl . mapr strongr . assoc`
 94 | public export
 95 | interface CatFunctor cat cat f => StrongFunctor
 96 |     (0 cat : Hom obj)
 97 |     (0 ten : obj -> obj -> obj)
 98 |     (0 f : obj -> obj) | cat,ten,f where
 99 |   constructor MkStrongFunctor
100 |   ||| The left tensor strength.
101 |   strongl : {a,b : _} -> cat (a `ten` f b) (f $ a `ten` b)
102 |   ||| The right tensor strength.
103 |   strongr : {a,b : _} -> cat (f a `ten` b) (f $ a `ten` b)
104 |
105 | ||| An endofunctor has *tensorial costrength* if it is compatible with
106 | ||| a monoidal category's tensor product in a way that is dual to a
107 | ||| tensorial strength. Generally, `cat` is a monoidal category with
108 | ||| `ten` as its tensor product, though this is not enforced by the
109 | ||| interface.
110 | |||
111 | ||| This is the interface-style definition of a costrong functor. For
112 | ||| the record-style definition, see `Control.Category.Records.CostrongFunctorR`.
113 | |||
114 | ||| Laws (when `cat` is a monoidal category):
115 | ||| * `unitl . costrongl = map unitl`
116 | ||| * `unitr . costrongr = map unitr`
117 | ||| * `costrongl . map assoc' = assoc' . mapr costrongl . costrongl`
118 | ||| * `costrongr . map assoc' = assoc' . mapl costrongr . costrongr`
119 | ||| * `mapl costrongl . cstrongr = assoc' . mapr costrongr . costrongl`
120 | public export
121 | interface CatFunctor cat cat f => CostrongFunctor
122 |     (0 cat : Hom obj)
123 |     (0 ten : obj -> obj -> obj)
124 |     (0 f : obj -> obj) | cat,ten,f where
125 |   constructor MkCostrongFunctor
126 |   ||| The left tensor costrength.
127 |   costrongl : {a,b : _} -> cat (f $ a `ten` b) (a `ten` f b)
128 |   ||| The right tensor costrength.
129 |   costrongr : {a,b : _} -> cat (f $ a `ten` b) (f a `ten` b)
130 |
131 |
132 | ------------------------------------------------------------
133 | -- Existing Instances
134 | ------------------------------------------------------------
135 |
136 | namespace LaxMonFunctor
137 |   public export
138 |   [Id] {ten,i : _} -> Category cat => LaxMonFunctor cat ten i cat ten i Prelude.id
139 |       using CatFunctor.Id where
140 |     fjoin = id
141 |     funit = id
142 |
143 | namespace MonFunctor
144 |   public export
145 |   [Id] {ten,i : _} -> Category cat => MonFunctor cat ten i cat ten i Prelude.id
146 |       using LaxMonFunctor.Id where
147 |     fjoin' = id
148 |     funit' = id
149 |
150 | namespace StrongFunctor
151 |   public export
152 |   [Id] {ten : _} -> Category cat => StrongFunctor cat ten Prelude.id
153 |       using CatFunctor.Id where
154 |     strongl = id
155 |     strongr = id
156 |
157 | namespace CostrongFunctor
158 |   public export
159 |   [Id] {ten : _} -> Category cat => CostrongFunctor cat ten Prelude.id
160 |       using CatFunctor.Id where
161 |     costrongl = id
162 |     costrongr = id
163 |
164 |
165 | -- These instances should not be used unless necessary, as they have
166 | -- poor runtime quantity behavior. Prefer `Typ` over base's `Morphism`
167 | -- and `Kleisli` over base's `Kleislimorphism`.
168 |
169 | namespace LaxMonFunctor
170 |   ||| Convert a Prelude `Applicative` into a lax monoidal endofunctor
171 |   ||| over `Morphism`.
172 |   public export
173 |   [MorFromApplicative] Applicative f => LaxMonFunctor Morphism Pair () Morphism Pair () f
174 |       using CatFunctor.MorFromFunctor where
175 |     fjoin = Mor $ \(x,y) => (,) <$> x <*> y
176 |     funit = Mor $ const $ pure ()
177 |
178 |   ||| Convert a Prelude `Applicative` into a lax monoidal endofunctor
179 |   ||| over the function category.
180 |   public export
181 |   [FuncFromApplicative] Applicative f => LaxMonFunctor (~~>) Pair () (~~>) Pair () f
182 |       using CatFunctor.FuncFromFunctor where
183 |     fjoin (x,y) = (,) <$> x <*> y
184 |     funit = const $ pure ()
185 |
186 | namespace StrongFunctor
187 |   ||| Convert a Prelude `Functor` into a strong functor over
188 |   ||| `Morphism`.
189 |   public export
190 |   [MorFromFunctor] Functor f => StrongFunctor Morphism Pair f
191 |       using CatFunctor.MorFromFunctor where
192 |     strongl = Mor $ \(x,y) => map (x,) y
193 |     strongr = Mor $ \(x,y) => map (,y) x
194 |
195 |   ||| Convert a Prelude `Functor` into a strong functor over the
196 |   ||| function category.
197 |   public export
198 |   [FuncFromFunctor] Functor m => StrongFunctor (~~>) Pair m
199 |       using CatFunctor.FuncFromFunctor where
200 |     strongl (x,y) = map (x,) y
201 |     strongr (x,y) = map (,y) x
202 |
203 |   ||| Convert a Prelude `Applicative` into a strong functor over
204 |   ||| `Morphism`.
205 |   public export
206 |   [MorFromApplicative] Applicative f => Bitraversable ten => StrongFunctor Morphism ten f
207 |       using CatFunctor.MorFromFunctor where
208 |     strongl = Mor $ bitraverse pure id
209 |     strongr = Mor $ bitraverse id pure
210 |
211 |   ||| Convert a Prelude `Applicative` into a strong functor over the
212 |   ||| function category.
213 |   public export
214 |   [FuncFromApplicative] Applicative f => Bitraversable ten => StrongFunctor (~~>) ten f
215 |       using CatFunctor.FuncFromFunctor where
216 |     strongl = bitraverse pure id
217 |     strongr = bitraverse id pure
218 |