Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a state monad that does error handling as well?

I need to write a state monad that can also support error handling. I was thinking of using the Either monad for this purpose because it can also provide details about what caused the error. I found a definition for a state monad using the Maybe monad however I am unable to modify it to use Either, instead of Maybe. Here's the code:

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}
like image 323
HaskellNoob Avatar asked Oct 31 '10 14:10

HaskellNoob


1 Answers

Consider using ExceptT from Control.Monad.Trans.Except (instead of using 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

If you aren't comfortable with Monads and Monad transformers then I'd do that first! They are a huge help and programmer productivity performance win.

like image 193
Thomas M. DuBuisson Avatar answered Sep 18 '22 06:09

Thomas M. DuBuisson