take (-1) [] is [].
What are the reasons to prefer this over a partial function, that is, an error?
Are there use cases where this property is exploited?
take (-1) [] is [].
What are the reasons to prefer this over a partial function, that is, an error?
Are there use cases where this property is exploited?
On
take and drop are similar to the left-substring and right-substring functions, and it's proven in practice to be convenient for those not raise an error for negative or invalid lengths.
For example - a padding function:
pad :: Int -> String -> String
pad n str = (repeat (n - length str) ' ') ++ str
and here is a variant to pad with another string:
padWith :: String -> Int -> String -> String
padWith field n str = (take (n - length str) field) ++ str
Splitting a list in chunks of (at most)
npieces requirestaketo be total:Also, the current definition ensures
for any
nandxs.Arguably, we should have both
takeAtMostandtakeAtLeast, the latter being the partial variant (or instead returningMaybe).A similar concern arises from
zip, which is total as well, even when applied to lists of unequal length. Still, that is frequently exploited in the idiomzip [1..] xswhich pairs every element of the list with its own index.Keep however in mind that I am not arguing that a total function is always the preferred one. On many, many programming tasks obtaining a bug-revealing exception is a bliss compared with obtaining the wrong result and having no idea about where the bug is. Or even worse, getting a wrong yet plausible result, and not even discovering there is a bug.