Haskell Io Error Handling
Contents |
I/O errorsAttributes of I/O errorsTypes of I/O errorIOErrorType predicatesThrowing and catching I/O errorsDescriptionStandard IO Errors.Synopsistype IOError = IOExceptionuserError :: String -> IOErrormkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath ->
Haskell Catch Error
IOErrorannotateIOError :: IOError -> String -> Maybe Handle -> haskell either monad Maybe FilePath -> IOErrorisAlreadyExistsError :: IOError -> BoolisDoesNotExistError :: IOError -> BoolisAlreadyInUseError :: IOError haskell error -> BoolisFullError :: IOError -> BoolisEOFError :: IOError -> BoolisIllegalOperation :: IOError -> BoolisPermissionError :: IOError -> BoolisUserError :: IOError -> BoolioeGetErrorType
Haskell Error Monad
:: IOError -> IOErrorTypeioeGetLocation :: IOError -> StringioeGetErrorString :: IOError -> StringioeGetHandle :: IOError -> Maybe HandleioeGetFileName :: IOError -> Maybe FilePathioeSetErrorType :: IOError -> IOErrorType -> IOErrorioeSetErrorString :: IOError -> String -> IOErrorioeSetLocation :: IOError -> String -> IOErrorioeSetHandle :: IOError -> Handle -> IOErrorioeSetFileName
Error Handling Definition
:: IOError -> FilePath -> IOErrordata IOErrorTypealreadyExistsErrorType :: IOErrorTypedoesNotExistErrorType :: IOErrorTypealreadyInUseErrorType :: IOErrorTypefullErrorType :: IOErrorTypeeofErrorType :: IOErrorTypeillegalOperationErrorType :: IOErrorTypepermissionErrorType :: IOErrorTypeuserErrorType :: IOErrorTypeisAlreadyExistsErrorType :: IOErrorType -> BoolisDoesNotExistErrorType :: IOErrorType -> BoolisAlreadyInUseErrorType :: IOErrorType -> BoolisFullErrorType :: IOErrorType -> BoolisEOFErrorType :: IOErrorType -> BoolisIllegalOperationErrorType :: IOErrorType -> BoolisPermissionErrorType :: IOErrorType -> BoolisUserErrorType :: IOErrorType -> BoolioError :: IOError -> IO acatchIOError :: IO a -> (IOError -> IO a) -> IO atryIOError :: IO a -> IO (Either IOError a)modifyIOError :: (IOError -> IOError) -> IO a -> IO aI/O errorstype IOError = IOException Source #The Haskell 2010 type for exceptions in the IO monad. Any I/O operation may raise an IOError instead of returning a result. For a more general type of exception, including also those that arise in pure code, see Exception.In
Mar 2015 Bartosz Milewski View Markdown source Previous content: 9. Evaluator Next types of error handling content: 11. State Monad Go up to: Basics of Haskell See
Data Error Handling
all content by Bartosz Milewski Sections Either May Be Better than MaybeAbstracting the Either PatternThe Either error handling in operating system MonadType ClassesSolution to the Expression ProblemThe Monad TypeclassExercisesThe Symbolic Calculator So Far Show me how you handle errors and I'll tell you what programmer you are. Error https://hackage.haskell.org/package/base/docs/System-IO-Error.html handling is fundamental to all programming. Language support for error handling varies from none whatsoever (C) to special language extensions (exceptions in C++, Java, etc.). Haskell is unique in its approach because it's expressive enough to let you build your own error handling frameworks. Haskell doesn't need built-in exception support: it implements it in libraries.We've https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/10_Error_Handling seen one way of dealing with errors: calling the error function that terminates the program. This works fine for runtime assertions, which alert us to bugs in the program. But many "errors" are actually expected. We've seen one such example: Data.Map.lookup fails when called with a key that's not present in the map. The possibility of failure is encoded in the Maybe return type of lookup. It's interesting to compare this with similar functions in other languages. In C++, for instance, std::map defines multiple accessor functions varying only in their failure behavior:at throws an exceptionfind returns an empty iteratoroperator[] inserts a dummy value using a default constructor for it.The last one is the most bizarre of the three. Since the array access operator must return a reference, even if the key is not found, it has to create a dummy value. The behavior of at is potentially dangerous if the client forgets to catch the exception. Of the three, find is the safe
it has been four years since the original publication of the article. Does this affect the veracity of the original article? Some names have changed, and some of the original advice given may have been a bit... dodgy. We’ll take a look at http://blog.ezyang.com/2011/08/8-ways-to-report-errors-in-haskell-revisited/ each of the recommendations from the original article, and also propose a new way of conceptualizing all of Haskell’s error reporting mechanisms. I recommend reading this article side-to-side with the old article. 1. Use error No change. My personal recommendation is that you should only use error in cases which imply programmer error; that is, you have some invariant that only a programmer (not an end-user) could have violated. And don’t forget, you should probably see if you can enforce error handling this invariant in the type system, rather than at runtime. It is also good style to include the name of the function which the error is associated with, so you say “myDiv: division by zero” rather than just “Division by zero.” Another important thing to note is that error e is actually an abbreviation for throw (ErrorCall e), so you can explicitly pattern match against this class of errors using: import qualified Control.Exception as E example1 :: Float -> haskell io error Float -> IO () example1 x y = E.catch (putStrLn (show (myDiv1 x y))) (\(ErrorCall e) -> putStrLn e) However, testing for string equality of error messages is bad juju, so if you do need to distinguish specific error invocations, you may need something better. 2. Use Maybe a No change. Maybe is a convenient, universal mechanism for reporting failure when there is only one possible failure mode and it is something that a user probably will want to handle in pure code. You can easily convert a returned Maybe into an error using fromMaybe (error "bang") m. Maybe gives no indication what the error was, so it’s a good idea for a function like head or tail but not so much for doSomeComplicatedWidgetThing. 3. Use Either String a I can’t really recommend using this method in any circumstance. If you don’t need to distinguish errors, you should have used Maybe. If you don’t need to handle errors while you’re in pure code, use exceptions. If you need to distinguish errors in pure code, for the love of god, don’t use strings, make an enumerable type! However, in base 4.3 or later (GHC 7), this monad instance comes for free in Control.Monad.Instances; you no longer have to do the ugly Control.Monad.Error import. But there are some costs to having changed this: see below. 4. Use Monad and fail to generalize 1-3 If you at all a theoretici