Это так же просто, как
[x | x <- xs, p x]
Поскольку p :: a -> Bool
и xs :: [a]
, чтобы получить логическое значение, нам нужно применить функцию к аргументу;и согласно семантике понимания списка x :: a
.
Правило вывода типа application :
x :: a
p :: a -> b
-------------
p x :: b
И вам не нужно сопоставление с образцом, об этом позаботится понимание списка.
В общем, это
lcFilter :: (a -> Bool) -> [a] -> [a]
lcFilter p xs = [x | x <- xs, p]
Понимание списка - это весело.Они придерживаются одного правила:
[ ... | x <- (xs ++ ys), .... ] ===
[ ... | x <- xs, .... ] ++ [ ... | x <- ys , .... ]
Как следствие, у нас также есть
[ ... | x <- ([y] ++ ys), .... ] ===
[ ... | x <- [y], .... ] ++ [ ... | x <- ys , .... ] ===
[ ...{x/y} | ....{x/y} ] ++ [ ... | x <- ys , .... ]
, где {x/y}
означает "заменить x
на y
во всем" .Таким образом, список [a,b,...,n]
преобразуется по вашему определению в
[ a, b, ..., n ] ===>
[ a | p a] ++ [b | p b] ++ ... ++ [n | p n ]
Это может быть далее понято в терминах / служить хорошей иллюстрацией / концепций монад , илииз моноидов , но мы оставим это на другой день.:)