我需要编写一个状态monad,它也可以支持错误处理。我当时正在考虑将Either monad用于此目的,因为它也可以提供有关导致错误的原因的详细信息。我使用Maybe monad找到了状态monad的定义,但是我无法将其修改为使用Either而不是Maybe。这是代码:

newtype StateMonad a = StateMonad (State -> Maybe (a, State))

instance Monad StateMonad where
(StateMonad p) >>= k = StateMonad (\s0 -> case p s0 of
                                 Just (val, s1) -> let (StateMonad q) = k val in q s1
                                 Nothing -> Nothing)
return a = StateMonad (\s -> Just (a,s))

data State = State
{ log  :: String
, a    :: Int}

最佳答案

考虑使用ExceptT中的Control.Monad.Trans.Except(而不是使用Either)。

import Control.Monad.State
import Control.Monad.Trans.Except
import Control.Monad.Identity

data MyState = S

type MyMonadT e m a = StateT MyState (ExceptT e m) a

runMyMonadT :: (Monad m) => MyMonadT e m a -> MyState -> m (Either e a)
runMyMonadT m = runExceptT . evalStateT m

type MyMonad e a = MyMonadT e Identity a
runMyMonad m = runIdentity . runMyMonadT m

如果您对Monads和Monad变压器不满意,那我先做吧!它们是巨大的帮助,并且可以提高程序员的工作效率。

关于haskell - 我该如何编写也执行错误处理的状态monad?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4063592/

10-10 16:26