"filter" é uma função de ordem superior que recebe a condição p (um predicado) com que cada elemento da lista é testado.
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
Exemplos :
pares :: [Int] -> [Int]
pares l = filter even l
pares [1,2,3,4]
= filter even [1,2,3,4]
= filter even [2,3,4]
= 2 : filter even [3,4]
= 2 : filter even [4]
= 2 : 4 : filter even []
= 2:4:[] = [2,4]
-----------------------------------------------------------------------------------------
positivos :: [Double] -> [Double]
positivos xs = filter (>0) xs
Usando listas por compreensão, poderíamos definir a função "filter" assim:
filter p l = [ x | x <- l, p x ]
Consideremos as seguintes funções:
pares :: [Int] -> [Int]
pares [] = []
pares (x:xs) = if even x
then x : pares xs
else pares xs
Estas funções fazem coisas distintas entre si, mas a forma como operam é semelhante : selecionam da lista de entrada os elementos que verificam uma dada condição.
Estas funções têm um padrão de computação comum, e apenas diferem na condição com que cada elemento da lista é testado.
positivos :: [Double] -> [Double]
positivos [] = []
positivos (x:xs)
| x > 0 = x : positivos xs
| otherwise = positivos xs
A função "filter" do Prelude sintetiza este padrão de computação, abstraindo em relação à condição com que os elementos da lista são testados.