Haskell 自有单体变压器和提升

Haskell 自有单体变压器和提升,haskell,Haskell,您在上下文中似乎没有任何MonadTrans实例,因此lift不存在 但更重要的是,看看函数的类型。 x是类型a的值,返回x需要给出类型(解释器m)a的元素 为此,您需要使用数据构造函数解释器rmt,并给它一个m(解释器rm a) 这意味着回报的主体应该是 Interpreter.hs:25:20: Couldn't match expected type `InterpreterMT m a' with actual type `a2 -> t1

您在上下文中似乎没有任何MonadTrans实例,因此
lift
不存在

但更重要的是,看看函数的类型。
x
是类型
a
的值,
返回x
需要给出类型
(解释器m)a
的元素

为此,您需要使用数据构造函数
解释器rmt
,并给它一个
m(解释器rm a)

这意味着回报的主体应该是

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)

您在上下文中似乎没有任何MonadTrans实例,因此
lift
不存在

但更重要的是,看看函数的类型。
x
是类型
a
的值,
返回x
需要给出类型
(解释器m)a
的元素

为此,您需要使用数据构造函数
解释器rmt
,并给它一个
m(解释器rm a)

这意味着回报的主体应该是

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)

尼古拉斯说的。我没有使用无点样式,因此可能更容易理解类型。您可以查看示例实现以更好地了解变压器-

数据解释器RM a=EXE解释器a
|前解释程序a
newtype解释器rmt m a=解释器rmt{run解释器rmt::m(解释器rm a)}
实例(Monad m)=>Monad(rmt m)其中
--return::Monad m=>a->解释器rmt m a
return x=解释器rmt$(return.execrospector)x
--或者在您在下面定义MonadTrans之后
--返回x=提升。返回$x
--(>>=)::Monad m=>解释器m a->(a->解释器m b)->解释器m b
(>>=)ima f=RMT$do
每年RMT$f
(ProInterpreter a)->运行解释RMT$f a
实例MonadTrans解释器RMT,其中
--电梯:单子m=>MA->RMT m a

lift ma=explorermt$(return.execexplorer)=尼古拉斯说的话。我没有使用无点样式,因此可能更容易理解类型。您可以查看示例实现以更好地了解变压器-

数据解释器RM a=EXE解释器a
|前解释程序a
newtype解释器rmt m a=解释器rmt{run解释器rmt::m(解释器rm a)}
实例(Monad m)=>Monad(rmt m)其中
--return::Monad m=>a->解释器rmt m a
return x=解释器rmt$(return.execrospector)x
--或者在您在下面定义MonadTrans之后
--返回x=提升。返回$x
--(>>=)::Monad m=>解释器m a->(a->解释器m b)->解释器m b
(>>=)ima f=RMT$do
每年RMT$f
(ProInterpreter a)->运行解释RMT$f a
实例MonadTrans解释器RMT,其中
--电梯:单子m=>MA->RMT m a

lift ma=explorermt$(return.execexplorer)=我认为这意味着
explorermt(return(prointerpreter a))>=return
=
explorermt(return(execexplorer a))
违反了
x>=return=x
你完全正确。这是一个简化的Either定义,但重要的区别是我们只有一个类型参数,而不是两个类似的类型参数。应该将大小写表达式更改为
(ProInterpreter a)->return(ProInterpreter a)
,但是类型检查器会抛出一个错误,因为它无法将expeced
解释器m b
解释器m a
匹配。不幸的是,我不知道这个问题的解决方案。对,我认为这两种情况都应该将
f
应用于
a
,然后再次进行匹配,组合结果。在这个问题的答案中,我只是将解释器rmt简化为(某个)幺半群+WriterT,它的优点是清晰,但答案太复杂,不实用。我认为正确的monad实例将有效地内联monoid m+monad实例,用于(m,)/WriterT m
(return.execexplorer)=我认为这意味着
解释器rmt(return(prointerpreter a))>=return
=
解释器rmt(return(execexplorer a))
违反
x>=return=x
您完全正确。这是一个简化的Either定义,但重要的区别是我们只有一个类型参数,而不是两个类似的类型参数。应该将大小写表达式更改为
(ProInterpreter a)->return(ProInterpreter a)
,但是类型检查器会抛出一个错误,因为它无法将expeced
解释器m b
解释器m a
匹配。不幸的是,我不知道这个问题的解决方案。对,我认为这两种情况都应该将
f
应用于
a
,然后再次进行匹配,组合结果。在这个问题的答案中,我只是将解释器rmt简化为(某个)幺半群+WriterT,它的优点是清晰,但答案太复杂,不实用。我认为正确的monad实例将有效地内联一个monoidm+monad实例(m,)/WriterT m
(return.exe解释器)=
return . PropInterpreter $ x
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