Re: [Haskell-cafe] exceptions vs. Either

Sometimes the qualification of an error changes while it is propagated.
There was a discussion about this recently (on the ghc list I think)( The proposed (partial) solution is to use mapException: mapExceptionIO :: (Exception -> Exception) -> IO a -> IO a mapExceptionIO f io = Exception.catch io (\e -> throw $ f e) which would be used like: main = mapExceptionIO (\x -> ErrorCall $ showString "in main: " $ show x) $ do Exceptions can be thrown from anywhere, but can only be caught in the IO monad hence mapException must be in the IO monad. Map exception allows a kind of 'backtrace' allowing all functions in the call stack of a function which throws an exception to annotate the error message. Exceptions should only really be used for unpredictcable events, I find that the defintion of functions like head is lacking rigor... I would prefer to see: head :: [a] -> Maybe a head (a0:_) = Just a0 head _ = Nothing I think functions should only throw an exception if they are subject to the halting problem (the only way to tell if an algorith will fail is to run that algorith) - head and lots of other functions in the prelude are not subject to this, and in my opinion should really be returning Maybe... nobody said anything about me previous post about using the type system to have 'validated' types - does this mean everyone thinks its a good idea, or was it too off topic - too obvious? Keean.

Exceptions should only really be used for unpredictcable events, I find that the defintion of functions like head is lacking rigor... I would prefer to see:
head :: [a] -> Maybe a head (a0:_) = Just a0 head _ = Nothing
In principle, yes, but in practice, that would be silly. You use "head" just when you know for sure that the list is non-empty; if it is not, it's a "program error" for head, and an "impossible error" for the caller. Consider: f (head xs) -- old style vs f (case head xs of Some x -> x; None -> error "whoops") -- Schupke style It should be clear that this function would never be used - if head had this signature, programmers would just write f (case xs of (x:_) -> x; [] -> error "whoops") -- direct style --KW 8-)

MR K P SCHUPKE
head :: [a] -> Maybe a head (a0:_) = Just a0 head _ = Nothing
Argh, no! Violating the precondition of head is a bug in the caller, I want it to crash, but I also want to know where. Wrapping it up in Maybe (or any other error propagation) is not a solution. I don't want to write a lot of unwrapping code in all the callers, just to get a trackable error message in the (few) cases where I'm using the function incorrectly. Neither do I want to write (\x -> if null x then error ("__FILE__:__LINE__") else head x) everywhere instead of head, nor pollute my code with error tracking, but otherwise meaningless strings. (Which is what I generally do when I get this kind of anonymous error. if null x then error "foo" else head x. A mechanism for a function to report the caller site would obliviate the need for all this ugliness. -kzm Hmm...if I run it through CPP and #define HEAD (\x -> if null x then error ("__FILE__:__LINE__") else head x) is the __LINE__ resolved at the place of declaration or at the place of usage? -- If I haven't seen further, it is by standing in the footprints of giants

Ketil Malde
Hmm...if I run it through CPP and #define HEAD (\x -> if null x then error ("__FILE__:__LINE__") else head x) is the __LINE__ resolved at the place of declaration or at the place of usage?
According to the C standard, at the position of /usage/ of the macro `HEAD'. Incidentally, cpphs does not yet implement __FILE__ or __LINE__ replacements. Is their usage widespread amongst Haskell users? Regards, Malcolm
participants (4)
-
Keith Wansbrough
-
Ketil Malde
-
Malcolm Wallace
-
MR K P SCHUPKE