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:
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