views:

183

answers:

3
foldl1 (+) []

How do I catch the resulting error?

+5  A: 

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

Pablo Fernandez
+7  A: 

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"
Don Stewart
I think the program also as a bug in its exception andler :-)
Simon Marlow
This program is not a pipe.
Don Stewart
This exchange has brought me much appiness.
sclv
+2  A: 

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.

Chris Smith