Note, this question is not about "monoids in the category of endofunctors". Nor is it directly about
Functors (aMonadis always aFunctor, but this question is concerned mainly about monad transformers)
The docs on Haskell's SelectT monad transformer states that
SelectTis not a functor on the category of monads, and many operations cannot be lifted through it.
MaybeT, RWST, etc), but some not (ContT, SelectT)?A functor is a data type that implements the Functor typeclass. An applicative is a data type that implements the Applicative typeclass. A monad is a data type that implements the Monad typeclass. A Maybe implements all three, so it is a functor, an applicative, and a monad.
Functor categories serve as the hom-categories in the strict 2-category Cat. In the context of enriched category theory the functor category is generalized to the enriched functor category.
A Functor is kind of mapping of objects and morphisms that preserves composition and identity. We have two Categories: A and B . In Category A we have two objects a and b with morphism f . Our Functor is a mapping of objects a and b to Fa and Fb and mapping of morphisms, in this case single morphism: f to Ff .
Morphisms in this category are natural transformations between functors. Functors are often defined by universal properties; examples are the tensor product, the direct sum and direct product of groups or vector spaces, construction of free groups and modules, direct and inverse limits.
- What's the category of monads? What are the arrows in that category?
The category where the objects are monads, i.e., types T of kind Type -> Type with Monad instances, and the arrows A -> B are natural transformations between their underlying functors, conventionally represented in Haskell by functions of type forall x. A x -> B x (although strictly speaking parametricity is a stronger condition than naturality).
There’s an implementation of this in the mmorph package.
The initial object in this category is Identity, since for any monad T there’s exactly one natural transformation forall x. Identity x -> T x. Dually, I think the final object is Const ().
- Why are some monad transformers functors on the category of monads (
MaybeT,RWST, etc), but some not (ContT,SelectT)?
A functor in this category would need a lifted fmap:
fmap'
:: forall m n. (Monad m, Monad n)
=> (forall x. m x -> n x) -> forall x. T m x -> T n x
And you can’t implement this in general for ContT and SelectT. I’m not sure precisely why, but it seems to depend on variance: we’re trying to implement a covariant functor, but ContT and SelectT are invariant in their underlying monads, e.g., m occurs both positively and negatively in the (a -> m r) -> m r inside a ContT r m a.
- What good does it do, from a programming perspective, to be a functor on the category of monads? Why should I care as a consumer of the library?
If you have a general way to “run” a monad m in a monad n, you can’t necessarily lift that into ContT or SelectT; you’re stuck with the more restricted mapping operations like these:
mapSelectT :: (m a -> m a) -> SelectT r m a -> SelectT r m a
mapContT :: (m r -> m r) -> ContT r m a -> ContT r m a
Where the underlying monad and result type are fixed. So you can’t always freely hoist actions within a stack that uses these transformers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With