Advertisement
Condiamond

Adjoint functors

Dec 23rd, 2022 (edited)
2,029
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 4.29 KB | Source Code | 0 0
  1. {-# OPTIONS_GHC -Wno-missing-export-lists #-}
  2.  
  3. {-# LANGUAGE DeriveFunctor         #-}
  4. {-# LANGUAGE InstanceSigs          #-}
  5. {-# LANGUAGE LambdaCase            #-}
  6. {-# LANGUAGE MultiParamTypeClasses #-}
  7. {-# LANGUAGE ScopedTypeVariables   #-}
  8. {-# LANGUAGE TypeOperators         #-}
  9.  
  10. module Adjunctions where
  11.  
  12. import           Control.Comonad (Comonad (duplicate, extract))
  13. import           Control.Monad   (ap)
  14.  
  15. ----------------------
  16. -- ADJOINT FUNCTORS --
  17. --      f -| g      --
  18. ----------------------
  19.  
  20. class (Functor f, Functor g) => Adjunction f g where
  21.   unit :: a -> g (f a)
  22.   unit = leftAdjunct id
  23.  
  24.   counit :: f (g b) -> b
  25.   counit = rightAdjunct id
  26.  
  27. -- Hom(f a, b) ≃ Hom(a, g b)
  28.  
  29.   leftAdjunct :: (f a -> b) -> a -> g b
  30.   leftAdjunct func = fmap func . unit
  31.  
  32.   rightAdjunct :: (a -> g b) -> f a -> b
  33.   rightAdjunct func = counit . fmap func
  34.  
  35.   {-# MINIMAL unit, counit | leftAdjunct, rightAdjunct #-}
  36.  
  37. -----------------------
  38. -- PRODUCT and ARROW --
  39. -----------------------
  40.  
  41. --                   Env     Reader
  42. --                   Writer  Traced
  43. instance Adjunction ((,) x) ((->) x) where
  44.   unit :: a -> x -> (x, a)
  45.   unit a = \x -> (x, a)
  46.  
  47.   counit :: (x, x -> b) -> b
  48.   counit (x, f) = f x
  49.  
  50. -------------------
  51. -- VOID and UNIT --
  52. -------------------
  53.  
  54. data Void1 p deriving Functor
  55.  
  56. data Unit1 p = Unit1 deriving Functor
  57.  
  58. instance Adjunction Void1 Unit1 where
  59.   unit :: a -> Unit1 (Void1 a)
  60.   unit _ = Unit1
  61.  
  62.   counit :: Void1 (Unit1 b) -> b
  63.   counit = \case {}
  64.  
  65. ---------------------
  66. -- SUM and PRODUCT --
  67. ---------------------
  68.  
  69. data (f |+| g) a = Left1 (f a) | Right1 (g a) deriving Functor
  70.  
  71. data (f |*| g) a = f a :*: g a deriving Functor
  72.  
  73. instance (Adjunction f g, Adjunction f' g') => Adjunction (f |+| f') (g |*| g') where
  74.   unit :: a -> (g |*| g') ((f |+| f') a)
  75.   unit x = leftAdjunct Left1 x :*: leftAdjunct Right1 x
  76.  
  77.   counit :: (f |+| f') ((g |*| g') b) -> b
  78.   counit = \case
  79.     Left1 fp   -> rightAdjunct (\(gb :*: _) -> gb) fp
  80.     Right1 f'p -> rightAdjunct (\(_ :*: g'b) -> g'b) f'p
  81.  
  82. ---------------------------
  83. -- IDENTITY and IDENTITY --
  84. ---------------------------
  85.  
  86. newtype IdentityT f a = IdentityT { runIdentityT :: f a } deriving Functor
  87.  
  88. instance Adjunction f g => Adjunction (IdentityT f) (IdentityT g) where
  89.   unit :: a -> IdentityT g (IdentityT f a)
  90.   unit = IdentityT . leftAdjunct IdentityT
  91.  
  92.   counit :: IdentityT f (IdentityT g b) -> b
  93.   counit = rightAdjunct runIdentityT . runIdentityT
  94.  
  95. ---------------------------------
  96. -- COMPOSITION and COMPOSITION --
  97. ---------------------------------
  98.  
  99. newtype (g |.| f) a = Comp { runComp :: g (f a) } deriving Functor
  100.  
  101. instance (Adjunction f g, Adjunction f' g') => Adjunction (f' |.| f) (g |.| g') where
  102.   unit :: a -> (g |.| g') ((f' |.| f) a)
  103.   unit = Comp . leftAdjunct (leftAdjunct Comp)
  104.  
  105.   counit :: (f' |.| f) ((g |.| g') a) -> a
  106.   counit = rightAdjunct (rightAdjunct runComp) . runComp
  107.  
  108. ---------------------
  109. -- FREE and COFREE --
  110. ---------------------
  111.  
  112. data Free f a = Pure a | Free (f (Free f a)) deriving Functor
  113.  
  114. data Cofree f a = a :< f (Cofree f a) deriving Functor
  115.  
  116. instance Adjunction f g => Adjunction (Free f) (Cofree g) where
  117.   unit :: a -> Cofree g (Free f a)
  118.   unit x = Pure x :< leftAdjunct (\funit -> leftAdjunct (\free -> Free (free <$ funit)) x) ()
  119.  
  120.   counit :: Free f (Cofree g a) -> a
  121.   counit = error "IT'S A NIGHTMARE"
  122.  
  123. --------------------------------------------------------------------------------------
  124. -- If f -| g, then we CAN instantiate Monad for (g |.| f) and Comonad for (f |.| g) --
  125. --------------------------------------------------------------------------------------
  126.  
  127. instance Adjunction f g => Monad (g |.| f) where
  128.   return :: a -> (g |.| f) a
  129.   return = Comp . unit
  130.  
  131.   (>>=) :: (g |.| f) a -> (a -> (g |.| f) b) -> (g |.| f) b
  132.   c >>= f = joinComp $ fmap f c
  133.     where
  134.       joinComp :: (g |.| f) ((g |.| f) a) -> (g |.| f) a
  135.       joinComp (Comp gfcgfa) = Comp $ fmap (counit . fmap runComp) gfcgfa
  136.  
  137. instance Adjunction f g => Comonad (f |.| g) where
  138.   extract :: (f |.| g) a -> a
  139.   extract = counit . runComp
  140.  
  141.   duplicate :: (f |.| g) a -> (f |.| g) ((f |.| g) a)
  142.   duplicate (Comp fga) = Comp $ fmap (fmap Comp . unit) fga
  143.  
  144. instance (Adjunction f g) => Applicative (g |.| f) where
  145.   pure = return
  146.  
  147.   (<*>) = ap
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement