В Haskell вы, вероятно, просто использовали бы функцию более высокого порядка, такую как zipWith
.Таким образом, вы можете сделать что-то вроде этого:
diff [] = []
diff ls = zipWith (-) (tail ls) ls
Обратите внимание, как я обработал случай []
отдельно - если вы передадите пустой список в tail
, вы получите ошибку времени выполнения и Haskellers действительно , действительно ненавижу ошибки времени выполнения.Однако в моей функции я гарантирую, что ls
не пустой, поэтому использование tail
безопасно.(Для справки tail
просто возвращает все, кроме первого элемента списка. Он такой же, как cdr
в Схеме.)
Это просто берет список и его хвост и объединяет все элементы, используя(-)
функция.
При наличии списка [1,2,3,4]
это будет выглядеть примерно так:
zipWith (-) [2,3,4] [1,2,3,4]
[2-1, 3-2, 4-3]
[1,1,1]
Это обычная модель: вы можете удивительно много вычислять, умно используястандартные функции высшего порядка.Вы также не боитесь передавать список и свой собственный хвост функции - нет никакой мутации, которая могла бы вас испортить, и компилятор часто очень умен в оптимизации кода, подобного этому.
По совпадению, если вынапример списочные выражения и не против включения расширения ParallelListComp
, вы можете написать zipWith (-) (tail ls) ls
так:
[b - a | a <- ls | b <- tail ls]