6 ms·
Yeah, I would agree that head, as it is, looks like a mistake. Instead of: head :: [a] -> a I would code it as: head :: [a] -> Maybe a returning Nothing
by lbolla 13y ago
Yeah, I would agree that head, as it is, looks like a mistake.
Instead of:
head :: [a] -> a
I would code it as:
head :: [a] -> Maybe a
returning Nothing for empty lists. Same applies to tail.
But others have very good reasons to disagree: http://stackoverflow.com/questions/6364409/why-does-haskells-head-crash-on-an-empty-list-or-why-doesnt-it-return-an http://stackoverflow.com/questions/6364409/why-does-haskells...
- tel 13y agoI don't see that answer arguing that `safeHead` is bad. Russell O'Connor just seems to be arguing that it'd not be possible for `head :: [a] -> a` to have a sentinel value `uhOh :: forall a . a` which you could pattern match on when `head []` is called... but `safeHead :: [a] -> Maybe a` is just fine since it has a different free theorem. In the comments on Real World Haskell people (Alex Stangl and Paul Johnson in particular) are talking about added complexity of deferring invariant errors, but since these are type-declared via `Maybe` it really helps to add safety. I personally have written many, many functions with partial types because I had forgotten about some assumed invariants and had them fixed by use of `safeHead`. NonEmptyList is pretty good for pre-handling all of the failure modes.