Note to other potential participants: Please feel free to use abstract or mathematical notation to make your point. If I find your answer unclear, I will ask for clarification, but otherwise you can express yourself in a convenient manner.
To be clear: I'm not looking for a "safe" head , and the choice of head in particular is exceptionally significant. The meat of the question follows the discussion of head and head' , which serve to provide context.
I’ve been hacking Haskell for several months (to the point that it has become my main language), but I’m admittedly not well informed about some of the more advanced concepts and details of the philosophy language (although I’m more than ready to learn). My question then is not so technical (if it is not, and I just do not understand), since he is one of the philosophers.
In this example, I'm talking about head .
As I understand it, you will know
Prelude> head [] *** Exception: Prelude.head: empty list
This follows from head :: [a] -> a . Fair. Obviously, you cannot return an element (without the slightest) type. But at the same time, it’s easy (if not trivial) to define
head' :: [a] -> Maybe a head' [] = Nothing head' (x:xs) = Just x
I saw a little discussion of this here in the comments section of some statements. Noteworthy that one alex stangle says
“There are good reasons not to make everything“ safe ”and throw exceptions when preconditions are violated.
I do not necessarily doubt this statement, but I am curious what these "good reasons" are.
In addition, Paul Johnson says:
'For example, you can define "safeHead :: [a] → Maybe a", but instead of processing an empty list or proving that this cannot be, you need to process "Nothing" or prove that it can "Listen" .
The tone I read from this comment suggests that this is a noticeable increase in complexity / complexity / something, but I'm not sure I understand that it is there.
One Stephen Pruzina says (in 2011, at least)
"There's a deeper reason why, for example, a head cannot be crash proof. To be polymorphic, but to process an empty list, the head should always return a variable of a type not found in any particular empty list. That would be Delphi, if Haskell could do this ... "
Is polymorphism lost by allowing empty list processing? If so, how and why? Are there any special cases that will make this obvious? There is enough response from @Russell O'Connor in this section. Any further thoughts are, of course, appreciated.
I will edit this as clarity and sentence dictate. Any thoughts, documents, etc. that you can provide will be most valuable.