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)
我有错误,我不知道为什么:
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)
答案 0 :(得分:5)
尼古拉斯说。我没有使用无点样式,因此理解类型可能会更容易些。您可以查看示例实现,以便更好地了解变换器 - 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
答案 1 :(得分:4)
您似乎在上下文中没有任何MonadTrans实例,因此lift
不存在。
但更重要的是,请查看函数的类型。
x
是a
类型的值,return x
需要提供(InterpreterMT m) a
类型的元素。
为此,您需要使用数据构造函数InterpreterMT
并为其指定m (InterpreterM a)
这意味着回归的主体应该像
return . PropInterpreter $ x