Exception handling in numeric computations (was Re: [Haskell-cafe] Use unsafePerformIO to catch Exception?)

Henning Thielemann 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
> madness.

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 
computations.

>  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 mailing list