What are the adjoint functor pairs corresponding to common monads in Haskell?

What you’re looking for is Kleisli category. It was originally developed to show that every monad can be constructed from two adjoint functors.

The problem is that Haskell Functor is not a generic functor, it’s an endo-functor in the Haskell category. So we need something different (AFAIK) to represent functors between other categories:

{-# LANGUAGE FunctionalDependencies, KindSignatures #-}
import Control.Arrow
import Control.Category hiding ((.))
import qualified Control.Category as C
import Control.Monad

class (Category c, Category d) => CFunctor f c d | f -> c d where
    cfmap :: c a b -> d (f a) (f b)

Notice that if we take -> for both c and d we get an endo-functor of the Haskell category, which is just the type of fmap:

cfmap :: (a -> b) -> (f a -> f b)

Now we have explicit type class that represents functors between two given categories c and d and we can express the two adjoint functors for a given monad. The left one maps an object a to just a and maps a morphism f to (return .) f:

-- m is phantom, hence the explicit kind is required
newtype LeftAdj (m :: * -> *) a = LeftAdj { unLeftAdj :: a }
instance Monad m => CFunctor (LeftAdj m) (->) (Kleisli m) where
    cfmap f = Kleisli $ liftM LeftAdj . return . f . unLeftAdj
    -- we could also express it as liftM LeftAdj . (return .) f . unLeftAdj

The right one maps an object a to object m a and maps a morphism g to join . liftM g, or equivalently to (=<<) g:

newtype RightAdj m a = RightAdj { unRightAdj :: m a }
instance Monad m => CFunctor (RightAdj m) (Kleisli m) (->) where
    cfmap (Kleisli g) = RightAdj . join . liftM g . unRightAdj
    -- this can be shortened as RightAdj . (=<<) g . unRightAdj

(If anybody know a better way how to express this in Haskell, please let me know.)

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)