Thats a wonderful idea. With that it will be so much easier to write
robust code without bloating the code with error checks.
I've always been annoyed that I couldn't trap arbitrary errors, say to
close down the application cleanly.
Now, we only need extendible data types, and then we have an (almost)
ML-like exception system :)
/Tommy
Simon L Peyton Jones wrote/a ecrit/skrev:
>
> Alastair Reid has been very quiet, so I'll pipe up for him.
>
> Here's a reasonable design for exceptions in Haskell:
>
> * A value of Haskell type T can be
> EITHER one of the values we know and love
> (bottom, or constructor, or function,
> depending on T),
>
> OR it can be a set of exceptional values.
>
> * raise :: String -> a
> (raise s) returns a single exceptional value, named by string s
>
> * All strict operations (case, +, etc) return the union of
> the exceptional values returned by their strict arguments
> For example, if both arguments to "+" return an exceptional value
> then "+" returns both. Similarly, any strict context.
>
> * handle :: (String -> IO a) -> IO a -> IO a
> (handle h a) tries to perform the action a.
> If doing so delivers a set of exceptional values then
> apply the exception handler h to the string that names
> one of them. It is not defined which of the exceptional
> values is picked.
>
>
> The neat thing about this is that the exceptions can
> be *raised* in arbitrary purely functional code, without
> violating referential transparency. The question of
> which exception is chosen is done in the IO monad, where
> of course it is allowed to be non-deterministic.
> The implementation does not keep sets of exceptional values,
> of course. It simply propagates the first one it trips
> over to the nearest enclosing handler.
>
> (It is likely that successive runs will actually give
> the same behaviour, but recompiling the program with
> (say) different optimisation levels might change the order
> of evaluation, and hence change which exception is tripped
> over first.)
>
> We're implementing an experimental version of this
> in GHC, integrated with the IO monad exceptions, so that
>
> handle :: (IOError -> IO a) -> IO a -> IO a
>
> and we add an extra constructor (UserError String) to the
> IOError type for exceptions raised by raise.
>
> Calls to "error" also show up as an exceptional value, of
> course.
>
> One merit of the system is that it chops out a tremendous
> number of run-time error checks in the IO monad, since
> we are now free to implement the mechanism with standard
> stack-unwinding techniques. Result: much better I/O performance.
>
>
> I'd be interested to know what people think of this.
>
> Simon