Search code examples
haskellmonadsfunctor

Why there is no `Cofunctor` typeclass in Haskell?


Monads get fmap from Functor typeclass. Why comonads don't need a cofmap method defined in a Cofunctor class?


Solution

  • Functor is defined as:

    class Functor f where
        fmap :: (a -> b) -> (f a -> f b)
    

    Cofunctor could be defined as follows:

    class Cofunctor f where
        cofmap :: (b -> a) -> (f b -> f a)
    

    So, both are technically the same, and that's why Cofunctor does not exist. "The dual concept of 'functor in general' is still 'functor in general'".

    Since Functor and Cofunctor are the same, both monads and comonads are defined by using Functor. But don't let that make you think that monads and comonads are the same thing, they're not.

    A monad is defined (simplifying) as:

    class Functor m => Monad where
        return :: a -> m a
        (>>=) :: m a -> (a -> m b) -> m b
    

    whether a comonad (again, simplified) is:

    class Functor w => Comonad where
        extract :: w a -> a
        extend :: (w a -> b) -> w a -> w b
    

    Note the "symmetry".


    Another thing is a contravariant functor, defined as:

    import Data.Functor.Contravariant
    class Contravariant f where
        contramap :: (b -> a) -> (f a -> f b)