Почему взять общую функцию

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 который связывает каждый элемент списка со своим собственным индексом.

Имейте в виду, однако, что я не утверждаю, что тотальная функция всегда является предпочтительной. Во многих, многих задачах программирования получение исключения для выявления ошибок - это блаженство по сравнению с получением неправильного результата и отсутствие представления о том, где находится ошибка. Или еще хуже, получая неправильный, но правдоподобный результат, и даже не обнаруживая ошибки.

Другие вопросы по тегам