Is there a library or typeclass for getting the transformer version of a monad?

≯℡__Kan透↙ 提交于 2020-01-02 01:18:08

问题


In my current project I've run into the need to turn various monads into their transformer counterparts e.g.

stateT :: Monad m => State s a -> StateT s m a
stateT stf = StateT $ return . runState stf

It's trivial to write these utility functions for the monads I need, but I was wondering if there already exists a library that contains this functionality for the standard monads and maybe a typeclass that abstracts this sort of transformation. Something like

class (Monad f, MonadTrans t) => LiftTrans f t | f -> t where
    liftT :: Monad m => f a -> t m a

("lift" is probably the wrong term to use here, but I wasn't sure what else to call it.)


回答1:


Check out function hoist from the mmorph package.

Its signature is

hoist :: Monad m => (forall a. m a -> n a) -> t m b -> t n b

Meaning that it can change the base monad underlying a transformer.

Now, in the trasformers package, many "basic" monads are implemented as transformers applied to the Identity monad, like this:

type State s = StateT s Identity

Therefore, we can define the following function (taken form the Generalizing base monads section of the mmorph documentation):

import Data.Functor.Identity

generalize :: (Monad m) => Identity a -> m a
generalize m = return (runIdentity m)

and combine it with hoist:

hoist generalize :: (Monad m, MFunctor t) => t Identity b -> t m b

This method won't work for simple monads which are not defined as transformers applied to Identity, like the Maybe and Either monads. You are stuck with hoistMaybe and hoistEither for these.




回答2:


You are trying to go the wrong way. If something is a transformer, than the plain version of it is the transformer applied to the Identity monad. (They are not always implemented like that directly, but should be equivalent modulo bottom.) But, not all monads are transformers (They need to be universally left or universally right adjoint in order to transform. [citation needed])

hoist and friends are super helpful, too, but I think it best to invert your process.



来源:https://stackoverflow.com/questions/20066858/is-there-a-library-or-typeclass-for-getting-the-transformer-version-of-a-monad

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!