如何在haskell中将功能提升到变形monad?

时间:2013-05-16 10:20:27

标签: 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 <- runMaybeT x
       return $ liftM f inner

但是我如何将此liftF概括为

liftF :: (MonadTrans t, Monad m) => (a -> b) -> t m a -> t m b

1 个答案:

答案 0 :(得分:5)

正如@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约束。

但你为什么要这样做?查看MaybeT的源代码 - 已经有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)

实际上,liftM与Functor的fmap相同:

instance (Functor m) => Functor (MaybeT m) where
    fmap f = mapMaybeT (fmap (fmap f))

您可以找到所有变形金刚的类似实例。

这是你要问的吗?您能否提供一些更具体的示例来展示您尝试做什么以及为什么,以及现有的Functor和Monad实例以何种方式无法满足您的需求?