Haskell 哈斯克尔。提升单子误差与局部函数

Haskell 哈斯克尔。提升单子误差与局部函数,haskell,Haskell,如何修复它以及为什么它是一个错误?好的,有两个问题 首先,lift具有以下签名: Couldn't match type `InterpreterMT (StateT Int (ReaderT Int (ErrorT String IO)))' with `StateT Int (ReaderT Int (ErrorT String IO))' Expected type: Interprete

如何修复它以及为什么它是一个错误?

好的,有两个问题

首先,
lift
具有以下签名:

  Couldn't match type `InterpreterMT
                           (StateT Int (ReaderT Int (ErrorT String IO)))'
                  with `StateT Int (ReaderT Int (ErrorT String IO))'
    Expected type: Interpreter ()
      Actual type: InterpreterMT
                     (InterpreterMT (StateT Int (ReaderT Int (ErrorT String IO)))) ()
    In the expression: lift $ local (\ x -> x) (interpreter stmts)
    In an equation for `interpreter':
        interpreter (Statements s stmts)
          = lift $ local (\ x -> x) (interpreter stmts)
所以你必须提供非转换的单体动作来提升。换句话说,您不能在提升的参数中使用
解释器rmt

因此,您需要将其展开:

lift :: (MonadTrans t, Monad m) => m a -> t m a
但是现在您的返回类型没有意义了:
runexplormt$…
具有类型

lift $ local id $ runInterpreterMT $ interpreter stmts
或者,将变压器堆栈缩短为
M

StateT Int (ReaderT Int (ErrorT String IO)) (InterpreterM ())
解释器
返回
解释器()
,即

M (InterpreterM ())
或者,缩短变压器组

InterpreterMT (StateT Int (ReaderT Int (ErrorT String IO))) ()
回到
lift
的类型,
ma->tma
变成
m(解释器rm())->解释器rmt m(解释器rm())
<代码>(解释器())不是
()

问题的根源是什么?您的
解释器rmt
实际上并不是一个monad转换器,因为它并不真正转换monad。它转换值

容易解决?如果您能够为
解释器rmt
找到一个合理的
Monad
实例(您提供的一个实例值得怀疑),那么您可以为
解释器rmt
定义一个
Monad>实例:

InterpreterMT M ()
(对于此特定定义,您将需要
未确定的指令

总的模式似乎是

instance MonadReader r m => MonadReader r (InterpreterMT m) where
  local f = InterpreterMT . local f . runInterpreterMT
  ...
请注意,这不是一个
函子


不确定你想在这里实现什么,但整个设计似乎。。。不发达的也许回到绘图板上,找出您想要的体系结构到底是什么样子是个好主意。

看起来您有
interprecrmt
包装
interprecrmt
,在将
解释器stmt
的结果传递给
本地id
之前,您是否只需要使用
运行解释器stmt
打开
解释器stmts的结果?好的,您需要为
解释器rm
解释器stmt
提供
Functor>和
应用程序
实例,如果这两行都应该是monad,那么这是一个要求,但最后一行只需要是
translatormt$local(\x->x)$runtranslatormt$translator stmts
。顺便说一句,你看起来想要做的事情看起来和免费的单子非常相似。你为什么这样做?为什么不使用
lift
?因为您也没有将
translatormt
作为
MonadTrans
的一个实例,并且
lift
返回一个必须实现
MonadTrans
的类型的值@bheklillr,我确实创建了
MonadTrans
实例,但我没有附加此代码。是我的错。但是,当我在第一篇文章中使用
lift
时,也存在问题。我编辑了我的第一篇文章。
instance MonadReader r m => MonadReader r (InterpreterMT m) where
  local f = InterpreterMT . local f . runInterpreterMT
  ...
inInterpreter f = InterpreterMT . f . runInterpreterMT