自己的Monad变压器和起重 [英] Own Monad Transformer and lifting

查看:131
本文介绍了自己的Monad变压器和起重的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

data InterpreterM a = ExeInterpreter a | PropInterpreter a

newtype InterpreterMT m a = InterpreterMT { runInterpreterMT :: m (InterpreterM a) }

instance (Monad m) => Monad (InterpreterMT m) where
    return x = lift . return
    x >>= f = InterpreterMT $ do
        m <- runInterpreterMT x
        case m of
            (ExeInterpreter a) -> runInterpreterMT (f a) 

instance MonadTrans InterpreterMT where
    lift m = lift .  (ExeInterpreter m)

我有错误,我不知道为什么:

I've got error, and I don't know why:

Interpreter.hs:25:20:
    Couldn't match expected type `InterpreterMT m a'
                with actual type `a2 -> t1 m1 a2'
    In the expression: lift . return
    In an equation for `return': return x = lift . return
    In the instance declaration for `Monad (InterpreterMT m)'

Interpreter.hs:32:18:
    Couldn't match expected type `InterpreterMT m a'
                with actual type `a0 -> t0 m0 a1'
    In the expression: lift . (ExeInterpreter m)
    In an equation for `lift': lift m = lift . (ExeInterpreter m)
    In the instance declaration for `MonadTrans InterpreterMT'

Interpreter.hs:32:27:
    Couldn't match expected type `a0 -> m0 a1'
                with actual type `InterpreterM (m a)'
    In the return type of a call of `ExeInterpreter'
    Probable cause: `ExeInterpreter' is applied to too many arguments
    In the second argument of `(.)', namely `(ExeInterpreter m)'
    In the expression: lift . (ExeInterpreter m)


推荐答案

尼古拉斯说了些什么。我没有使用无点风格,所以理解类型可能会更容易一些。你可以看看示例实现,以获得更好的感觉变压器 - Control.Monad.Trans.Class

What nicolas said. I didn't use the point-free style, so it might be a little bit easier to understand the types. You can look into example implementations to get a better feeling for transformers - Control.Monad.Trans.Class

data InterpreterM a = ExeInterpreter a
                    | PropInterpreter a

newtype InterpreterMT m a = InterpreterMT { runInterpreterMT :: m (InterpreterM a) }

instance (Monad m) => Monad (InterpreterMT m) where

--  return :: Monad m => a -> InterpreterMT m a
    return x = InterpreterMT $ (return . ExeInterpreter) x

-- or after you defined MonadTrans below
--  return x = lift . return $ x

--  (>>=) :: Monad m => InterpreterMT m a -> (a -> InterpreterMT m b) -> InterpreterMT m b
    (>>=) ima f = InterpreterMT $ do
        ia <- runInterpreterMT ima
        case ia of
            (ExeInterpreter  a) -> runInterpreterMT $ f a
            (PropInterpreter a) -> runInterpreterMT $ f a

instance MonadTrans InterpreterMT where

--  lift :: Monad m => m a -> InterpreterMT m a
    lift ma = InterpreterMT $ (return . ExeInterpreter) =<< ma

这篇关于自己的Monad变压器和起重的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆