* On Sunday, May 02 2010, Alexander Dunlap wrote:
>Of course, there are situations where it is really awkward to not use
>partial functions, basically because you *know* that an invariant is
>satisfied and there is no sane course of action if it isn't. To take a
>f ys = let xs = (1:ys) in last xs
>uses the partial function "last". Rewriting it in the "non-partial style" gives
>f ys = case (1:ys) of
>  -> Nothing
> xs -> Just (last xs)
>but what possible meaning could a caller of the function ascribe to a
>"Nothing" result? It just means that there is a bug in f, which is
>what an error would tell you anyway. Of course, this particular
>function could easily be rewritten in such a way to be total, but I
>believe there are more complex examples where it is awkward/impossible
>to do so.
You're just showing how difficult it is to reason about when the use of
partial functions is safe: undefined), with your `non-partial style'
version, you still leave open the case of (Just undefined), since we
cannot convince ourselves that last only fails on empty lists here...
One case where Maybe or Either might be less preferable to an exception
is for the output of a lexer (ex. alex does this) because it means you
can get some tokens without without forcing the whole input, and do some
IO based on the results even if there is a mistake in either reading the
input from disk or lexing it.
But I think this situation of (ab)using lazy IO and exceptions is an
oversimplification, and you can find appropriate alternatives such as
iteratee which are more explicit about what is going on.
Haskell-Cafe mailing list