Henning Thielemann
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. 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. So we need to use method (b), to use monad to parse our matrix around.
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. 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. And because I don't always want to deal with such problem in the IO monad, I create this beast 'unsafePerformIO . try . evaluate' to convert some potential disastrous result to 'Either Disaster Result'. You might argue that Haskell actually deals with such numerical problem with 'NaN', 'Infinite'. But, some numerical operations behave weird with these special values, and using 'isNan', 'isInfinite' alike is just another big mess. They are going to be all over the place and not actually better than 'case ... of' and 'fromMaybe'. I can't really think of another option for this kind of situation, apart from letting my code to be infected by NumericCancerMonad. If anyone on this list has some thoughts on this matter, please share them. Many thanks. -- c/* __o/* <\ * (__ */\ <