Почему взять общую функцию
take (-1) []
является []
,
Каковы причины, чтобы предпочесть это частичной функции, то есть ошибке?
Есть ли случаи использования, когда это свойство используется?
2 ответа
take
а также drop
похожи на функции левой подстроки и правой подстроки, и на практике доказано, что они удобны для тех, кто не вызывает ошибку для отрицательных или недействительных длин.
Например - функция заполнения:
pad :: Int -> String -> String
pad n str = (repeat (n - length str) ' ') ++ str
и вот вариант дополнить другой строкой:
padWith :: String -> Int -> String -> String
padWith field n str = (take (n - length str) field) ++ str
Разделение списка на куски (не более) n
штук требует take
быть полным:
chunks n [] = []
chunks n xs = take n xs : chunks n (drop n xs)
Кроме того, текущее определение обеспечивает
take n xs ++ drop n xs == xs
для любого n
а также xs
,
Возможно, мы должны иметь оба takeAtMost
а также takeAtLeast
последний является частичным вариантом (или вместо этого возвращает Maybe
).
Аналогичная проблема возникает из zip
, что также является общим, даже когда применяется к спискам неодинаковой длины. Тем не менее, это часто используется в идиоме zip [1..] xs
который связывает каждый элемент списка со своим собственным индексом.
Имейте в виду, однако, что я не утверждаю, что тотальная функция всегда является предпочтительной. Во многих, многих задачах программирования получение исключения для выявления ошибок - это блаженство по сравнению с получением неправильного результата и отсутствие представления о том, где находится ошибка. Или еще хуже, получая неправильный, но правдоподобный результат, и даже не обнаруживая ошибки.