自己的Monad变压器和起重 [英] Own Monad Transformer and lifting
本文介绍了自己的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屋!
查看全文