Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ErrorT catchError in practice

I have a very typical setup with a set of functions in the IO monad that can throw errors. To date I have just been dealing with errors at the end of the monad chain by pattern matching the Either result from runErrorT:

replLisp :: LispScope -> String -> IO String
replLisp s input = do
  result <- runErrorT (evalLisp s input)
  return $ either (id) (show) result 

I would now like to add some error handling to my Hacked little scheme, but I'm having trouble making the type checker happy.

How does one use catchError? An example or two would be helpful.


This is my latest attempt:

catch :: [LispVal] -> IOThrowsError LispVal
catch [action rescue] = do
  eval action >>= catchError $ eval rescue
like image 889
John F. Miller Avatar asked Feb 20 '26 07:02

John F. Miller


1 Answers

Here is an example use of catchError to recover from a prior call to throwError:

import Control.Monad.Error
import Control.Monad.Identity

type MyMonad = ErrorT String Identity
runMyMonad = runIdentity . runErrorT

main = do
        let x = runMyMonad (func 5 0)
        print x

func :: Double -> Double -> MyMonad Double
func w x = do
        y <- (divider x) `catchError` (\_ -> return 1)
        return (w + y)

divider :: Double -> MyMonad Double
divider x = do
        when (x == 0) (throwError "Can not divide by zero!")
        return (10 / x)

Despite passing 0 in for division we can complete with the handlers result of 1 to obtain output of Right 6.0.

Does this help? Your question didn't really say what the issue was.

like image 90
Thomas M. DuBuisson Avatar answered Feb 24 '26 14:02

Thomas M. DuBuisson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!