2023-03-06 12:31:03 -05:00
|
|
|
module Data.Profunctor.Closed
|
|
|
|
|
2023-03-06 21:36:44 -05:00
|
|
|
import Data.Morphisms
|
2023-03-06 12:31:03 -05:00
|
|
|
import Data.Profunctor.Types
|
|
|
|
import Data.Profunctor.Functor
|
|
|
|
import Data.Profunctor.Strong
|
|
|
|
|
|
|
|
%default total
|
|
|
|
|
|
|
|
|
2023-03-07 22:15:08 -05:00
|
|
|
------------------------------------------------------------------------------
|
|
|
|
-- Closed interface
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
||| Closed profunctors preserve the closed structure of a category.
|
|
|
|
|||
|
|
|
|
||| Laws:
|
|
|
|
||| * `lmap (. f) . closed = rmap (. f) . closed`
|
|
|
|
||| * `closed . closed = dimap uncurry curry . closed`
|
|
|
|
||| * `dimap const ($ ()) . closed = id`
|
2023-03-06 12:31:03 -05:00
|
|
|
public export
|
|
|
|
interface Profunctor p => Closed p where
|
2023-03-07 22:15:08 -05:00
|
|
|
||| The action of a closed profunctor.
|
2023-03-06 12:31:03 -05:00
|
|
|
closed : p a b -> p (x -> a) (x -> b)
|
2023-03-06 12:32:34 -05:00
|
|
|
|
|
|
|
|
2023-03-07 22:15:08 -05:00
|
|
|
------------------------------------------------------------------------------
|
2023-03-08 15:05:28 -05:00
|
|
|
-- Implementations
|
2023-03-07 22:15:08 -05:00
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 21:36:44 -05:00
|
|
|
Closed Morphism where
|
|
|
|
closed (Mor f) = Mor (f .)
|
|
|
|
|
2023-03-07 22:15:08 -05:00
|
|
|
||| A named implementation of `Closed` for function types.
|
|
|
|
||| Use this to avoid having to use a type wrapper like `Morphism`.
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 21:36:44 -05:00
|
|
|
[Function] Closed (\a,b => a -> b) using Profunctor.Function where
|
|
|
|
closed = (.)
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 21:36:44 -05:00
|
|
|
Functor f => Closed (Costar f) where
|
|
|
|
closed (MkCostar p) = MkCostar $ \f,x => p (map ($ x) f)
|
|
|
|
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
curry' : Closed p => p (a, b) c -> p a (b -> c)
|
|
|
|
curry' = lmap (,) . closed
|
|
|
|
|
2023-03-07 22:15:08 -05:00
|
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
-- Closure
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
2023-03-06 12:33:14 -05:00
|
|
|
-- Helper functions for working with function types
|
|
|
|
hither : (s -> (a, b)) -> (s -> a, s -> b)
|
|
|
|
hither h = (fst . h, snd . h)
|
|
|
|
|
|
|
|
yon : (s -> a, s -> b) -> s -> (a,b)
|
|
|
|
yon h s = (fst h s, snd h s)
|
|
|
|
|
|
|
|
|
2023-03-07 22:15:08 -05:00
|
|
|
||| The comonad generated by the reflective subcategory of profunctors that
|
|
|
|
||| implement `Closed`.
|
2023-03-06 12:32:34 -05:00
|
|
|
public export
|
|
|
|
record Closure p a b where
|
|
|
|
constructor MkClosure
|
2023-03-06 16:44:26 -05:00
|
|
|
runClosure : forall x. p (x -> a) (x -> b)
|
2023-03-06 12:32:34 -05:00
|
|
|
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
Profunctor p => Profunctor (Closure p) where
|
|
|
|
dimap f g (MkClosure p) = MkClosure $ dimap (f .) (g .) p
|
|
|
|
lmap f (MkClosure p) = MkClosure $ lmap (f .) p
|
|
|
|
rmap f (MkClosure p) = MkClosure $ rmap (f .) p
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
ProfunctorFunctor Closure where
|
|
|
|
promap f (MkClosure p) = MkClosure (f p)
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
ProfunctorComonad Closure where
|
|
|
|
proextract (MkClosure p) = dimap const ($ ()) p
|
|
|
|
produplicate (MkClosure p) = MkClosure $ MkClosure $ dimap uncurry curry p
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
Strong p => GenStrong Pair (Closure p) where
|
|
|
|
strongl (MkClosure p) = MkClosure $ dimap hither yon $ first p
|
|
|
|
strongr (MkClosure p) = MkClosure $ dimap hither yon $ second p
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
Profunctor p => Closed (Closure p) where
|
2023-03-06 16:44:26 -05:00
|
|
|
closed p = runClosure $ produplicate p
|
2023-03-06 12:33:14 -05:00
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
Profunctor p => Functor (Closure p a) where
|
|
|
|
map = rmap
|
|
|
|
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
close : Closed p => p :-> q -> p :-> Closure q
|
|
|
|
close f p = MkClosure $ f $ closed p
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
unclose : Profunctor q => p :-> Closure q -> p :-> q
|
2023-03-06 16:44:26 -05:00
|
|
|
unclose f p = dimap const ($ ()) $ runClosure $ f p
|
2023-03-06 12:33:14 -05:00
|
|
|
|
|
|
|
|
2023-03-07 22:15:08 -05:00
|
|
|
------------------------------------------------------------------------------
|
2023-03-06 12:32:34 -05:00
|
|
|
-- Environment
|
2023-03-07 22:15:08 -05:00
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
2023-03-06 12:32:34 -05:00
|
|
|
|
2023-03-07 22:15:08 -05:00
|
|
|
||| The monad generated by the reflective subcategory of profunctors that
|
|
|
|
||| implement `Closed`.
|
2023-03-06 12:32:34 -05:00
|
|
|
public export
|
|
|
|
data Environment : (p : Type -> Type -> Type) -> Type -> Type -> Type where
|
|
|
|
MkEnv : ((z -> y) -> b) -> p x y -> (a -> z -> x) -> Environment p a b
|
|
|
|
|
2023-03-06 12:33:14 -05:00
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
Profunctor (Environment p) where
|
|
|
|
dimap f g (MkEnv l m r) = MkEnv (g . l) m (r . f)
|
|
|
|
lmap f (MkEnv l m r) = MkEnv l m (r . f)
|
|
|
|
rmap g (MkEnv l m r) = MkEnv (g . l) m r
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
ProfunctorFunctor Environment where
|
|
|
|
promap f (MkEnv l m r) = MkEnv l (f m) r
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
ProfunctorMonad Environment where
|
|
|
|
propure p = MkEnv ($ ()) p const
|
|
|
|
projoin (MkEnv {x=x',y=y',z=z'} l' (MkEnv {x,y,z} l m r) r') = MkEnv (ll . curry) m rr
|
|
|
|
where
|
|
|
|
ll : (z' -> z -> y) -> b
|
|
|
|
ll zr = l' (l . zr)
|
|
|
|
rr : a -> (z', z) -> x
|
|
|
|
rr a (b, c) = r (r' a b) c
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
ProfunctorAdjunction Environment Closure where
|
|
|
|
prounit p = MkClosure (MkEnv id p id)
|
|
|
|
procounit (MkEnv l (MkClosure x) r) = dimap r l x
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
Closed (Environment p) where
|
|
|
|
closed {x=x'} (MkEnv {x,y,z} l m r) = MkEnv l' m r'
|
|
|
|
where
|
|
|
|
l' : ((z, x') -> y) -> x' -> b
|
|
|
|
l' f x = l (\z => f (z,x))
|
|
|
|
r' : (x' -> a) -> (z, x') -> x
|
|
|
|
r' f (z,x) = r (f x) z
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
Profunctor p => Functor (Environment p a) where
|
|
|
|
map = rmap
|
|
|
|
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
environment : Closed q => p :-> q -> Environment p :-> q
|
|
|
|
environment f (MkEnv l m r) = dimap r l $ closed (f m)
|
|
|
|
|
2023-03-30 13:32:45 -04:00
|
|
|
public export
|
2023-03-06 12:33:14 -05:00
|
|
|
unenvironment : Environment p :-> q -> p :-> q
|
|
|
|
unenvironment f p = f (MkEnv ($ ()) p const)
|