[Haskell-cafe] Re: Exception handling in numeric computations
Xiao-Yong Jin
xj2106 at columbia.edu
Tue Mar 24 17:14:17 EDT 2009
Jake McArthur <jake at pikewerks.com> writes:
> Xiao-Yong Jin wrote:
> | 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.
>
> I disagree. If you try to take the inverse of a noninvertable matrix,
> this is an *error* in your code. Catching an error you created in pure
> code and patching it with chewing gum it is just a hack. A monadic
> approach (I'm putting Either/Maybe under the same umbrella for brevity)
> is the only solution that makes any sense to me, and I don't think it's
> ugly as you are making it out to be.
>
Then, why is 'div' not of type 'a -> a -> ArithExceptionMonad a' ?
Why does it throws this /ugly/ /error/ when it is applied to
0? Why is it not using some beautiful
'ArithExceptinoMonad'? Is 'Control.Exception' just pure
/ugly/ and doesn't make any sense?
>
> | 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.
>
> For functions that don't know or don't care about failure, just use fmap
> or one of its synonyms.
>
> ~ scalarMult 2 <$> invMat x
>
> See? The scalarMult function is pure, as it should be. There is no
> madness here.
Of course, 'scalarMult' is invulnerable and free of monad.
But take a look at the following functions,
> f1 = scalarMult 2 . invMat
> f2 l r = l `multMat` invMat r
> ff :: Matrix -> Matrix -> YetAnotherBiggerMonad Matrix
> ff x y = do let ff' = f1 x + f2 y
> put . (addMat ff') . f1 << get
> tell $ f2 ff'
> when (matrixWeDontLike (f1 ff') $
> throwError MatrixWeDontLike
> return $ scalarMult (1/2) ff'
Yes, I know, it's not really complicate to rewrite the above
code. But, what do I really gain from this rewrite?
--
c/* __o/*
<\ * (__
*/\ <
More information about the Haskell-Cafe
mailing list