Control.monad.error
type classes)Safe HaskellSafeLanguageHaskell98Control.Monad.ErrorContentsMonads with error handlingThe ErrorT monad transformerExample 1: Custom Error Data TypeExample 2: Using ErrorT Monad TransformerDescriptionDeprecated: Use Control.Monad.Except insteadComputation type:Computations which may fail or throw exceptions.Binding strategy:Failure records information about the cause/location of the failure. Failure values bypass the bound function, other values are used as inputs to the bound function.Useful for:Building computations from sequences of functions that may fail or using exception handling to structure error handling.Zero and plus:Zero is represented by an empty error and the plus operation executes its second argument if the first fails.Example type:Either String a
The Error monad (also called the Exception monad).Synopsisclass Monad m => MonadError e m | m -> e wherethrowError :: e -> m acatchError :: m a -> (e -> m a) -> m aclass Error a wherenoMsg :: astrMsg :: String -> anewtype ErrorT e m a :: * -> (* -> *) -> * -> * = ErrorT {runErrorT :: m (Either e a)}runErrorT :: ErrorT e m a -> m (Either e a)mapErrorT :: (m (Either e a) -> n (Either e' b)) -> ErrorT e m a -> ErrorT e' n bmodule Control.Monadmodule Control.Monad.Fixmodule Control.Monad.TransMonads with error handlingclass Monad m => MonadError e m | m -> e where SourceThe strategy of combining computations that can throw exceptions by bypassing bound functions from the point an exception is thrown to the point that it is handled.Is parameterized over the type of error information and the monad type constructor. It is common to use Either String
as the monad type constructor for an error monad in which error descriptions take the form of strings. In that case and many other common cases the resulting monad is already defined as an instance of the MonadError class. You can also define your own error type and/or use a monad type constructor other than Either String
or Either String a
The Error monad (also called the Exception monad).Synopsisclass Monad m => MonadError https://hackage.haskell.org/package/mtl/docs/Control-Monad-Error.html e m | m -> e wherethrowError :: e -> m acatchError :: m a -> (e -> m a) -> m anewtype ExceptT e m a :: * -> (* -> *) -> * -> * = ExceptT (m (Either e a))type Except e = ExceptT e IdentityrunExceptT :: ExceptT e m https://hackage.haskell.org/package/mtl/docs/Control-Monad-Except.html a -> m (Either e a)mapExceptT :: (m (Either e a) -> n (Either e' b)) -> ExceptT e m a -> ExceptT e' n bwithExceptT :: Functor m => (e -> e') -> ExceptT e m a -> ExceptT e' m arunExcept :: Except e a -> Either e amapExcept :: (Either e a -> Either e' b) -> Except e a -> Except e' bwithExcept :: (e -> e') -> Except e a -> Except e' amodule Control.Monadmodule Control.Monad.Fixmodule Control.Monad.TransMonads with error handlingclass Monad m => MonadError e m | m -> e where SourceThe strategy of combining computations that can throw exceptions by bypassing bound functions from the point an exception is thrown to the point that it is handled.Is parameterized over the type of error information and the monad type constructor. It is common to use Either String
as the monad type constructor for an error monad in which error descriptions take
the Maybe MonadUse of EitherCustom Data Types for ErrorsMonadic Use of EitherExceptionsFirst Steps with ExceptionsLaziness and Exception HandlingUsing handleSelective Handling of ExceptionsI/O ExceptionsThrowing ExceptionsDynamic ExceptionsExercisesError handling in monadsA tiny parsing frameworkExercises Error handling is one http://book.realworldhaskell.org/read/error-handling.html of the most important—and overlooked—topics for programmers, regardless of the language used. In Haskell, you will find two major types of error handling employed: "pure" error handling and exceptions. When we speak of "pure" error handling, we are referring to algorithms that do not require anything from the IO monad. We can often implement error handling for them by simply using Haskell's expressive data type system to our advantage. Haskell also has an exception system. Due to the complexities of lazy evaluation, exceptions in Haskell can be thrown anywhere, but only caught within the IO monad. In this chapter, we'll consider both. Error Handling with Data Types Let's begin our discussion of error handling with a very simple function. Let's say that we wish to perform division on a series of numbers. We have a constant numerator, but wish to vary the denominator. We might come up with a function like this: -- file: ch19/divby1.hs divBy :: Integral a => a -> [a] -> [a] divBy numerator = map (numerator `div`) Very simple, right? We can play around with this a bit in ghci: ghci> divBy 50 [1,2,5,8,10] [50,25,10,6,5] ghci> take 5 (divBy 100 [1..]) [100,50,33,25,20] This behaves as expected: 50 / 1 is 50, 50 / 2 is 25, and so forth. [38] This even worked with the infinite list [1..]. What happens if we sneak a 0 into our list somewhere? ghci> divBy 50 [1,2,0,8,10] [50,25,*** Exception: divide by zero Isn't that interesting? ghci started displaying the output, then stopped with an exception when it got to the zero. That's lazy evaluation at work—it calculated results as needed. As we will see later in this chapter, in the absence of an explicit exception handler, this exception will crash t