Exception handling in numeric computations (was Re: [Haskell-cafe]
Use unsafePerformIO to catch Exception?)
lemming at henning-thielemann.de
Tue Mar 24 16:34:13 EDT 2009
On Tue, 24 Mar 2009, Xiao-Yong Jin wrote:
>> invMat :: Matrix -> Matrix
> You won't be able to invert all the matrix, mathematically.
> And computationally, even a larger set of matrix might fail
> to be inverted because of the finite precision. It is
> relatively easier and more efficient to spot such a problem
> within this 'invMat' function. Because testing the
> singularity of a matrix is equally hard as invert it. So
> all I can do when 'invMat' spot a singular matrix are
> a) Return Either/Maybe to signal an error.
This is the way to go.
> b) Wrap it in a monad.
Either and Maybe are monads. These monads behave like exceptions in other
languages. I like to call these exceptions.
> c) Define a dynamic exception and throw it.
You cannot throw an exception in code that does not return Maybe, Either,
IO or such things. You can only abuse 'undefined' and turn it into a
defined value later by a hack. Think of 'undefined' as an infinite loop,
that cannot detected in general. GHC is kind enough to detect special
cases, in order to simplify debugging. But this should be abused for
exceptional return values.
> The problem is that there will be many functions using such
> a function to invert a matrix, making this inversion
> function return Either/Maybe or packing it in a monad is
> just a big headache. It is impractical to use method (a),
> because not every function that uses 'invMat' knows how to
> deal with 'invMat' not giving an answer.
How shall it deal with 'undefined' then? 'undefined' can only be handled
by a hack, so Maybe or Either are clearly better.
>> invMat :: Matrix -> NumericCancerMonad Matrix
> It hides the exceptional nature of numerical computations
> very well, but it is cancer in the code. Whenever any
> function wants to use invMat, it is mutated. This is just
No it makes explicit what's going on. This is the idea of functional
programming. You have nice Applicative infix operators in order to write
everything in a functional look anyway. In contrast, I think it is mad
that there is no function of type
mulInt :: Int -> Int -> Maybe Int
which allows us to catch overflows without using hacks. This function
could be easily integrated in a compiler, since the CPUs show by a flag,
that an overflow occurs. In most high level languages this is not
possible, and thus programming in an overflow-proof way needs additional
> You don't want to make all the code to be monadic just because of
> singularities in numeric calculation. Therefore, in my opinion, method
> (c) is my only option.
Then better stick to MatLab. :-(
More information about the Haskell-Cafe