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?
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)
n
pieces requirestake
to be total:Also, the current definition ensures
for any
n
andxs
.Arguably, we should have both
takeAtMost
andtakeAtLeast
, 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..] xs
which 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.