3
다른 것들 중에서도 오류 기능을 가진 기본 모나드를 제공하는 모나드 변환기를 정의하고 싶습니다. 변형 된 모나드는 기본 모나드가 MonadPlus의 인스턴스 여야합니다. 그러나 MonTPlus 인스턴스를 정의하는 방법을 알아낼 수 없으므로 ErrorT 변환기가 두 개 이상의 대답을 반환합니다 (둘 이상의 대답이있는 경우). 내 두 시도는 아래 코드에 있습니다. 코드 끝에는 기본 모나드가 []
인 경우 모나드 변환기가 어떻게 동작해야하는지 보여주는 문이 있습니다. 감사.ErrorT 상단에 변압기에 대한 MonadPlus 인스턴스 정의
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"]
줄 끝의 모든 공백 문자로 도대체 무엇이 다릅니 까? –