instance (Monad m, MonadAttempt m) => MonadAttempt (StateT s m) where
attempt a m = do s <- get
lift $ attempt a $ do (x, _) <- runStateT m s
return x
instance (Error e, Monad m, MonadAttempt m) => MonadAttempt (ErrorT e m) where
attempt a m = lift $ attempt a $ do e <- runErrorT m
case e of
Left _ -> return a
Right x -> return x
Wednesday, January 19, 2011
Corrected Instances for the MonadAttempt class
In my previous post, I outlined the MonadAttempt class that I had created to solve a problem with code generation using a state monad in Haskell. This morning, with a much clearer mind, I was able to create much cleaner instances for the StateT and ErrorT monads:
Labels:
Corrections,
Haskell,
Monads
Subscribe to:
Post Comments (Atom)
You can improve your MonadState some more using the 'evalStateT' function instead of 'runStateT'; it only returns the final value of the computation and not the final state.
ReplyDeleteattempt a m = get >>= lift . attempt a . evalStateT m
(The point-free version comes naturally when doing this change).
Similarly, using the 'either' function you can improve the MonadError instance:
attempt a m = lift . attempt a $ either (const a) id `liftM` runErrorT m
Have fun!
Thanks! I forgot about that function when I went to write these. That is indeed much nicer.
ReplyDelete