Haskell 在ErrorT之上为转换器定义MonadPlus实例

Haskell 在ErrorT之上为转换器定义MonadPlus实例,haskell,monads,monad-transformers,monadplus,Haskell,Monads,Monad Transformers,Monadplus,我想定义一个monad转换器,它赋予基本monad错误功能。如果基本monad是,则转换后的monad应该是MonadPlus的实例,但是我不知道如何定义MonadPlus实例,以便error transformer返回多个答案(如果有多个答案)。我的两次尝试都在下面的代码中。在代码的末尾,是一条语句,显示了如果基本monad是[],monad转换器应该如何工作。谢谢 import Control.Monad.Error import Control.Monad.Trans.Class dat

我想定义一个monad转换器,它赋予基本monad错误功能。如果基本monad是,则转换后的monad应该是MonadPlus的实例,但是我不知道如何定义MonadPlus实例,以便error transformer返回多个答案(如果有多个答案)。我的两次尝试都在下面的代码中。在代码的末尾,是一条语句,显示了如果基本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"] 
import Control.Monad.Error
导入控制.Monad.Trans.Class
数据MyTrans m a=MyTrans{runMyTrans::ErrorT String m a}
实例Monad m=>Monad(MyTrans m),其中
return=MyTrans。举起返回
m>>=f=MyTrans$do x MonadPlus(MyTrans m),其中
mzero=MyTrans$提升mzero
--尝试#1(仅显示第一个元素)
m`mplus`n=MyTrans$(runMyTrans m)`mplus`(runMyTrans n)
--尝试#2(不完整:参见未定义的语句)
--m`mplus`n=MyTrans$
--举个例子
--左->未定义
--右t->return r`mplus`return t
类型MyMonad=MyTrans[]
x=返回1::MyMonad Int
y=MyTrans$Throwerr“错误”::MyMonad Int
z=x`mplus`y
main=do
打印$(runErrorT$runMyTrans z)--应为[右1,左“错误”]

当心:我只验证了这符合您要求的行为,而没有检查它是否符合
MonadPlus
法则。很有可能它违反了部分或全部规则!使用时请自行承担风险。

行尾的所有空格到底是怎么回事?
instance MonadPlus m => MonadPlus (MyTrans m a) where
    mzero = MyTrans (ErrorT mzero)
    MyTrans (ErrorT m) `mplus` MyTrans (ErrorT n) = MyTrans (ErrorT (m `mplus` n))