如何在haskell中将函数提升到变换后的monad?

如何在haskell中将函数提升到变换后的monad?,haskell,monads,monad-transformers,Haskell,Monads,Monad Transformers,我知道使用数据构造函数和run***函数 我可以将任何函数提升到特定的MonadTrans实例 像这样, import Control.Monad.Trans import Control.Monad.Trans.Maybe import Control.Monad liftF :: (Monad m) => (a -> b) -> MaybeT m a -> MaybeT m b liftF f x = MaybeT $ do inner <- r

我知道使用数据构造函数和run***函数

我可以将任何函数提升到特定的MonadTrans实例

像这样,

import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import Control.Monad

liftF :: (Monad m) => (a -> b) -> MaybeT m a -> MaybeT m b
liftF f x = MaybeT $ do
       inner <- runMaybeT x
       return $ liftM f inner

正如@thoferon所提到的,您只需使用
liftM

import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import Control.Monad (liftM)

liftF :: (Monad m) => (a -> b) -> MaybeT m a -> MaybeT m b
liftF f m = liftM f m

liftF' :: (MonadTrans t, Monad m, Monad (t m)) => (a -> b) -> t m a -> t m b
liftF' f m = liftM f m
(我不得不向
liftF'
添加一个额外的Monad约束)

但你为什么要这么做?查看的源代码--已经有一个Monad实例:

instance (Monad m) => Monad (MaybeT m) where
    fail _ = MaybeT (return Nothing)
    return = lift . return
    x >>= f = MaybeT $ do
        v <- runMaybeT x
        case v of
            Nothing -> return Nothing
            Just y  -> runMaybeT (f y)
您可以找到所有变压器的类似实例


这就是你要问的吗?你能提供一些更具体的例子来说明你想做什么,为什么,以及现有的Functor和Monad实例以什么方式不能满足你的需要吗?

为什么不使用
liftM
TM
本身就是单子。@thoferon,是的,但是
liftM
也不是广义的。因为在使用
liftM
之前,我必须编写
实例Monad(SomeMonadTrans m),其中…
,所以我仍然必须知道SomeMonadTrans。我的英语很抱歉。我的意思是,在
Monad
的情况下,只要
SomeType
Monad
的一个实例,我们就不需要重新定义
liftM
。对于通用MonadTrans t,我必须在使用
liftM
之前定义
TM
a
Monad
。有没有办法跳过这一步?或者说,对于每个通用的
MonadTrans
实例是否都有一个通用的
liftF
?@Znatz但是在标准库中,作为
MonadTrans
实例的每个数据类型也是
Monad
的实例,因此
liftM
将与所有转换器一起工作。谢谢。我现在明白了。我必须将
MonadTrans t=>tm
的泛型实例定义为
Monad
的实例,或者使用实例的数据构造函数。
instance (Monad m) => Monad (MaybeT m) where
    fail _ = MaybeT (return Nothing)
    return = lift . return
    x >>= f = MaybeT $ do
        v <- runMaybeT x
        case v of
            Nothing -> return Nothing
            Just y  -> runMaybeT (f y)
instance (Functor m) => Functor (MaybeT m) where
    fmap f = mapMaybeT (fmap (fmap f))