我想定义一个monad transformer,除了其他东西之外,它还赋予了一个基础monad错误功能。如果基本单子是,那么转换后的单子应该是MonadPlus的实例,但是我不知道如何定义MonadPlus实例,以便ErrorT转换器返回多个答案(如果有多个答案的话)。我的两次尝试是在下面的代码中。在代码的末尾,是一条语句,显示了如果基础monad为[],monad转换器应该如何工作。谢谢。
import Control.Monad.Error
import Control.Monad.Trans.Class
data MyTrans m a = MyTrans {runMyTrans :: ErrorT String m a}
instance Monad m => Monad (MyTrans m) where
return = MyTrans . lift . return
m >>= f = MyTrans $ do x <- runMyTrans m
runMyTrans (f x)
instance MonadTrans MyTrans where
lift m = MyTrans $ lift m
instance MonadPlus m => MonadPlus (MyTrans m) where
mzero = MyTrans $ lift mzero
-- Attempt #1 (Only reveals the first element)
m `mplus` n = MyTrans $ (runMyTrans m) `mplus` (runMyTrans n)
-- Attempt #2 (Incomplete: see undefined statements)
-- m `mplus` n = MyTrans $
-- lift $ do a <- runErrorT $ runMyTrans m
-- b <- runErrorT $ runMyTrans n
-- case a of
-- Right r 1
-- Left _ -> undefined
-- -> case b of
-- Left _ -> undefined
-- Right t -> return r `mplus` return t
type MyMonad = MyTrans []
x = return 1 :: MyMonad Int
y = MyTrans $ throwError "Error" :: MyMonad Int
z = x `mplus` y
main = do
print $ (runErrorT $ runMyTrans z) -- should be [Right 1, Left "Error"] 发布于 2012-12-19 06:07:09
instance MonadPlus m => MonadPlus (MyTrans m a) where
mzero = MyTrans (ErrorT mzero)
MyTrans (ErrorT m) `mplus` MyTrans (ErrorT n) = MyTrans (ErrorT (m `mplus` n))Beware:我只是验证了它是否具有您要求的行为,而没有检查它是否满足MonadPlus定律。它很可能会违反其中的一些或全部规则!使用风险自负。
https://stackoverflow.com/questions/13940558
复制相似问题