是否有用于获取monad的变换器版本的库或类型类?

时间:2013-11-19 08:45:01

标签: haskell monad-transformers

在我目前的项目中,我遇到了将各种monad变成变压器对应物的需要,例如。

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

为我需要的monad编写这些实用程序函数是微不足道的,但我想知道是否已经存在一个包含标准monad的这个功能的库,也许是一个抽象这种转换的类型类。像

这样的东西
class (Monad f, MonadTrans t) => LiftTrans f t | f -> t where
    liftT :: Monad m => f a -> t m a

(“升力”可能是在这里使用的错误术语,但我不知道还有什么可以称之为。)

2 个答案:

答案 0 :(得分:17)

mmorph包中查看功能hoist

它的签名是

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

这意味着它可以改变变压器下面的基础monad。

现在,在trasformers包中,许多“基本”monad被实现为应用于Identity monad的变换器,如下所示:

type State s = StateT s Identity

因此,我们可以定义以下函数(从mmorph文档的Generalizing base monads部分开始):

import Data.Functor.Identity

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

并将其与升降机结合使用:

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

此方法不适用于未定义为应用于Identity的变换器的简单monad,如MaybeEither monad。您可能会遇到hoistMaybehoistEither

答案 1 :(得分:0)

你试图走错路。如果某个东西是变换器,那么它的简单版本就是应用于Identity monad的变换器。 (它们并不总是像那样直接实现,但应该等效于模数底部。)但是,并非所有的monad都是变换器(它们需要普遍左边或普遍右边伴随才能变换。[需要引证])

升降机和朋友也非常有帮助,但我认为最好颠倒你的过程。