Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Haskell exception handling work?

foldl1 (+) []

How do I catch the resulting error?

like image 985
qrest Avatar asked Sep 05 '10 22:09

qrest


People also ask

How do you use try in Haskell?

try :: Exception e => IO a -> IO (Either e a) try takes an IO action to run, and returns an Either . If the computation succeeded, the result is given wrapped in a Right constructor. (Think right as opposed to wrong). If the action threw an exception of the specified type, it is returned in a Left constructor.


3 Answers

Pure code may throw asynchronous, imprecise exceptions, for example, when a partial function encounters input it has no case to handle.

These are logical errors, usually, indicating bugs in the program specification.

They may be caught in IO code (usually at an outer layer of the program), via an exception handler.

For example, to catch your missing case for the empty list,

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns        #-}

import Control.Exception

main = do
    handle (\(e :: SomeException) -> print $ "This program as a bug: " ++ show e) $ do
        let !v = foldl1 (+) ([] :: [Int])
        return ()

We can observe that the exception is caught, and the program terminates.

$ ./A
"This program as a bug: Prelude.foldl1: empty list"
like image 168
Don Stewart Avatar answered Oct 21 '22 20:10

Don Stewart


All you need to know about haskell exceptions (in an easy read :)

like image 45
Pablo Fernandez Avatar answered Oct 21 '22 19:10

Pablo Fernandez


Purist answer: the result is undefined (specifically, bottom). You can't do anything with it except crash if the value is used in any way to build the program's results. See Haskell 98 Report section 3.1. It specifies that such "errors cause immediate program termination and cannot be caught by the user."

It's best to check input values and handle them BEFORE they can get this far. Don't use fold1 if the list could have 0 elements.

In practice though, you can use the methods in the other answers to catch it in IO when using GHC. Exceptions cannot be caught in pure (non-IO) code because raising an exception is a change in control flow is a side effect, not a pure computation.

like image 36
Chris Smith Avatar answered Oct 21 '22 19:10

Chris Smith