
Donald Bruce Stewart wrote:
So all this talk of locating head [] and fromJust failures got me thinking:
Couldn't we just use rewrite rules to rewrite *transparently* all uses of fromJust to safeFromJust, tagging the call site with a location?
I'm sorry for shifting the topic: I'm wondering if, rather than trying to make an error message more informative, we ought to make sure that no error will ever arise? The fromJust and `head of empty list' errors are totally equivalent to the dereferencing of zero pointer in C++ or NullPointerException in Java. It pains me to see that exactly the same problem arises in Haskell -- keeping in mind that already in C++ and Java one may exterminate these errors given right encapsulations. Languages like Cyclone or Cw use the type system to eliminate such errors. Surely Haskell can do something about this? This topic has been discussed at length on this list. It seems that the discussion came to the conclusion that eliminating head of the empty list error is possible and quite easy in Haskell. http://www.haskell.org/pipermail/haskell-cafe/2006-September/017915.html http://www.haskell.org/pipermail/haskell-cafe/2006-September/017937.html As to fromJust: would the world come to an end if this function is just not available? Oftentimes when we get the value of the type |Maybe a|, the algorithm prescribes the actions for the case if this value is Nothing. Thus the function `maybe', the deconstructor, seems to be called for. And if we are dead sure that the |Maybe a| value is definitely |Just smth| and we need to extract this |smth|, we can always write maybe (assert False undefined) id value I like how this phrase stands out in the code, to remind me to double-check my certainty about the value (and perhaps, to re-factor the code). Similarly for empty lists: it is often algorithmically significant as it is the base case for our recursion/induction. Thus, we have to make the null check according to the algorithm anyway. The type system can carry the result of such a test, so we don't have to repeat it. The functions head and tail should operate on the newtype NonemptyList -- in which case they are total. Other list functions may remain as they are, because we can always `forget' the NonemptyList tag. The run-time overhead is zero, the notational overhead is not much: writing a few extra `fromNonemptyList'. Compare with writing `fromIntegral', especially in the FFI-related code. The Haskell type system can do far more complex things, for example, solve the pervasive SQL injections and cross-site scripting problems: http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-str... (This URL appeared on one of the recent Haskell Weekly News, btw). Surely we can do something about a far simpler problem of head [] and fromJust? We may have to adjust our coding styles a little. The adjustment doesn't appear extensive; besides, isn't the whole point of programming in Haskell is to think differently?