Рассмотрим описание filter
в документах :
filter
, примененный к предикату и списку, возвращает список тех элементов, которые удовлетворяют предикату; т.е. ,
filter p xs = [x | x <- xs, p x]
Чтобы объяснить это кому-то, кто не понимает понимания списка, можно сказать, что filter
имеет три случая:
- (простой случай), когда фильтруемый список пуст, результат также пуст
- когда заголовок фильтруемого списка удовлетворяет предикату, это часть результата
- в противном случае пропустите заголовок и отфильтруйте оставшуюся часть списка
Эти случаи соответствуют один к одному с тремя последними строками вашего вопроса.
Маленькие штрихи могут сделать определение более идиоматичным и, следовательно, более легким для чтения:
filter _ [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
Для пустого списка предикатом может быть что угодно, и подчеркивание явно показывает, что в этом случае это неважно.
Вместо сопоставления с (x:y)
, используя (x:xs)
- think: "ex and exes" - подчеркивает, что вы разделяете список на его голову (типа a
) и tail (типа [a]
, т.е. , список a
).
Наконец, выстраивание рекурсивных вызовов в filter
позволяет читателю увидеть, что в последнем случае пропущен x
.