Skip to content

Commit 346fd8e

Browse files
authored
Merge pull request #82 from coot/coyoneda-docs
Coyoneda docs - lets add some math ;)
2 parents 0e8a64d + da9ff3a commit 346fd8e

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

src/Data/Coyoneda.purs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,19 @@ data CoyonedaF f a i = CoyonedaF (i -> a) (f i)
2626
-- | The `Coyoneda` `Functor`.
2727
-- |
2828
-- | `Coyoneda f` is a `Functor` for any type constructor `f`. In fact,
29-
-- | it is the _free_ `Functor` for `f`.
29+
-- | it is the _free_ `Functor` for `f`, i.e. any natural transformation
30+
-- | `nat :: f ~> g`, can be factor through `liftCoyoneda`. The natural
31+
-- | transformation from `Coyoneda f ~> g` is given by `lowerCoyoneda <<<
32+
-- | hoistCoyoneda nat`:
33+
-- | ```purescript
34+
-- | lowerCoyoneda <<< hoistCoyoneda nat <<< liftCoyoneda $ fi
35+
-- | = lowerCoyoneda (hoistCoyoneda nat (Coyoneda $ mkExists $ CoyonedaF id fi)) (by definition of liftCoyoneda)
36+
-- | = lowerCoyoneda (coyoneda id (nat fi)) (by definition of hoistCoyoneda)
37+
-- | = unCoyoneda map (coyoneda id (nat fi)) (by definition of lowerCoyoneda)
38+
-- | = unCoyoneda map (Coyoneda $ mkExists $ CoyonedaF id (nat fi)) (by definition of coyoneda)
39+
-- | = map id (nat fi) (by definition of unCoyoneda)
40+
-- | = nat fi (since g is a Functor)
41+
-- | ```
3042
newtype Coyoneda f a = Coyoneda (Exists (CoyonedaF f a))
3143

3244
instance eqCoyoneda :: (Functor f, Eq1 f, Eq a) => Eq (Coyoneda f a) where
@@ -55,6 +67,12 @@ instance bindCoyoneda :: Bind f => Bind (Coyoneda f) where
5567
liftCoyoneda $
5668
runExists (\(CoyonedaF k fi) -> lowerCoyoneda <<< f <<< k =<< fi) e
5769

70+
-- | When `f` is a Monad then it is a functor as well. In this case
71+
-- | `liftCoyoneda` is not only a functor isomorphism but also a monad
72+
-- | isomorphism, i.e. the following law holds
73+
-- | ```purescript
74+
-- | liftCoyoneda fa >>= liftCoyoneda <<< g = liftCoyoneda $ fa >>= g
75+
-- | ```
5876
instance monadCoyoneda :: Monad f => Monad (Coyoneda f)
5977

6078
instance monadTransCoyoneda :: MonadTrans Coyoneda where
@@ -64,6 +82,12 @@ instance extendCoyoneda :: Extend w => Extend (Coyoneda w) where
6482
extend f (Coyoneda e) =
6583
runExists (\(CoyonedaF k fi) -> liftCoyoneda $ f <<< coyoneda k <<= fi) e
6684

85+
-- | As in the monad case: if `w` is a comonad, then it is a functor, thus
86+
-- | `liftCoyoneda` is an iso of functors, but moreover it is an iso of
87+
-- | comonads, i.e. the following law holds:
88+
-- | ```purescript
89+
-- | g <<= liftCoyoneda w = liftCoyoneda $ g <<< liftCoyoneda <<= w
90+
-- | ```
6791
instance comonadCoyoneda :: Comonad w => Comonad (Coyoneda w) where
6892
extract (Coyoneda e) = runExists (\(CoyonedaF k fi) -> k $ extract fi) e
6993

@@ -78,6 +102,21 @@ unCoyoneda :: forall f g a. (forall b. (b -> a) -> f b -> g a) -> Coyoneda f a -
78102
unCoyoneda f (Coyoneda e) = runExists (\(CoyonedaF k fi) -> f k fi) e
79103

80104
-- | Lift a value described by the type constructor `f` to `Coyoneda f`.
105+
-- |
106+
-- | Note that for any functor `f` `liftCoyoneda` has a right inverse
107+
-- | `lowerCoyoneda`:
108+
-- | ```purescript
109+
-- | liftCoyoneda <<< lowerCoyoneda $ (Coyoneda e)
110+
-- | = liftCoyoneda <<< unCoyoneda map $ (Coyoneda e)
111+
-- | = liftCoyonead (runExists (\(CoyonedaF k fi) -> map k fi) e)
112+
-- | = liftCoyonead (Coyoneda e)
113+
-- | = coyoneda id (Coyoneda e)
114+
-- | = Coyoneda e
115+
-- | ```
116+
-- | Moreover if `f` is a `Functor` then `liftCoyoneda` is an isomorphism of
117+
-- | functors with inverse `lowerCoyoneda`: we already showed that
118+
-- | `lowerCoyoneda <<< hoistCoyoneda id = lowerCoyoneda` is its left inverse
119+
-- | whenever `f` is a functor.
81120
liftCoyoneda :: forall f. f ~> Coyoneda f
82121
liftCoyoneda = coyoneda id
83122

0 commit comments

Comments
 (0)