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
(max 0 EXPR)
around does not seem to be that much of an effort. –
Maretz Splitting a list in chunks of (at most) n
pieces requires take
to be total:
chunks n [] = []
chunks n xs = take n xs : chunks n (drop n xs)
Also, the current definition ensures
take n xs ++ drop n xs == xs
for any n
and xs
.
Arguably, we should have both takeAtMost
and takeAtLeast
, the latter being the partial variant (or instead returning Maybe
).
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 idiom zip [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.
take
doesn't raise an error for negative inputs. –
Tactic drop
which - then - would have to be defined accordingly, too –
Maretz take 10 [1,2,3] == [1,2,3]
for chunks
to work. If take
were partial, chunks
would be partial as well except on lengths multiples of n
. –
Enamour take
is partial in another sense too (taking 10 elements from the [1,2,3] is hardly more possible than taking (-1) elements). So constraining it only for negative numbers would be incoherent. By the way, Ocaml zip (called combine
) throws when lists have different lengths, and I heard that's the pain. –
Amboina © 2022 - 2024 — McMap. All rights reserved.
IndexError
but slicing never raises anIndexError
: whenever the slice is out of bounds it simply returns the empty list. I've been coding in python for quite a bit and I must say that this behaviour is what you want from a pragmatic point of view. It allows to be sloppy when slicing, making code smaller and easier and 99.9% of the time the empty list would be the correct result anyway... – Whereto