[Haskell-cafe] Re: Exception handling in numeric computations

Xiao-Yong Jin xj2106 at columbia.edu
Tue Mar 24 17:29:00 EDT 2009

Daniel Yokomizo <daniel.yokomizo at gmail.com> writes:

> On Tue, Mar 24, 2009 at 1:27 PM, Xiao-Yong Jin <xj2106 at columbia.edu> wrote:
>> Henning Thielemann <lemming at henning-thielemann.de> writes:
>>> Try to never use exception handling for catching programming errors!
>>> Division by zero is undefined, thus a programming error when it
>>> occurs.
>>>  http://www.haskell.org/haskellwiki/Error
>>>  http://www.haskell.org/haskellwiki/Exception
>>>   I'm afraid, a Maybe or Either or Exceptional (see explicit-exception
>>> package) return value is the only way to handle exceptional return
>>> values properly. Maybe in the larger context of your problem zero
>>> denominators can be avoided? Then go this way.
>> Using div is just an example I'm testing with what I read in
>> the book Real World Haskell.  The real thing I'm trying to
>> do is inverting a matrix.  Say, I want to write
>>> 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.
>>  b) Wrap it in a monad.
>>  c) Define a dynamic exception and throw it.
> In general if a function is partial we can either make it total by
> extending its range or restricting its domain. Also we can signal it
> using runtime or compile-time mechanisms. Options a & b are equivalent
> (i.e. extend the range, compile-time notification) and option c is
> also another way of extending the range, but using runtime
> notification.
> If we try the other approach, we need to express the totality of
> invMat by restricting its domain, so we can add, for example, a
> phantom type to Matrix to signal it is invertible. As you need to
> construct the Matrix before trying to invert it you can always make
> the constructors smart enough to bundle the Matrix with such
> properties. Of course there's need to do some runtime verifications
> earlier, but the clients of invMat are required to do the verification
> earlier or pass it to their clients (up to the level that can handle
> with this issue):
> data Invertible
> tryInvertible :: Matrix a -> Maybe (Matrix Invertible)
> invMat :: Matrix Invertible -> Matrix Invertible
> You could use different forms of evidence (e.g. phantom types, type
> classes) but the idea is the same.

This is theoretically sound, we can make a type 'Integer
Invertible' and make a 'safeDiv' to get rid of one of the
ArithException.  But as I said above, "testing the
singularity of a matrix is equally hard as inverting it",
doing it with matrix is more impractical than make 'div'
safe.  I don't mind my haskell code runs 6 times slower than
c++ code.  But I'm not ready to make it 10 times slower just
because I want to do something twice and it might as well be
useless most of the time.
    c/*    __o/*
    <\     * (__
    */\      <

More information about the Haskell-Cafe mailing list