Рекурсия или понимание списка? - PullRequest
9 голосов
/ 09 июля 2011

Работая с Изучим вас на Haskell для хорошего блага , в главе о функциях высшего порядка автор рассматривает реализацию нескольких различных библиотечных функций. Когда я подошел к определению filter' (повторная реализация стандартной библиотечной функции filter), я подумал, что очевидным было следующее:

filter' f xs = [x | x <- xs, f x]

Но автор дает следующее более длинное рекурсивное определение:

filter' _ [] = []  
filter' p (x:xs)   
    | p x       = x : filter' p xs  
    | otherwise = filter' p xs

Оба определения делают одно и то же. Есть ли причина для этого? Является ли рекурсивное определение более производительным? Это более идиоматично для Haskell? Что-то еще?

Ответы [ 2 ]

13 голосов
/ 09 июля 2011

Вероятно, потому, что понимание списка - это просто синтаксический сахар, который в принципе переводится в рекурсивную форму.

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

Короче говоря, он показывает, как реализовать из довольно минимального набора базовых строительных блоков.

Это предположение, хотя - я сам не читал этот урок.

8 голосов
/ 09 июля 2011

Понимание списка - в значительной степени сахар для карты и фильтра в одной операции; Хотя он может использовать concatMap в бэкэнде. Обычно использование чего-то более высокого уровня абстракции для реализации чего-то более низкого уровня абстракции - это обман.

...