Podem-se definir funções usando listas por compreensão.


Exemplo: A função de ordenação de listas quick sort.

qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) = (qsort [y | y<-xs, y<x]) ++[x]++ (qsort [y | y<-xs, y>=x])

<aside> 💡 Esta versão do quick sort faz duas travessias da lista para fazer a sua partição e, por isso, é pior do que a versão anterior com a função auxiliar parte.

</aside>


Exemplo: Usando a função zip e listas por compreensão, podemos definir a função que calcula a lista de posições de um dado valor numa lista.

posicoes :: Eq a => a -> [a] -> [Int]
posicoes x l = [ i | (y,i) <- zip l [0..], x == y]

{- Porquê usar a função Zip :
Exemplo : zip [3,4,5,3,6,3,2] [0..]
          [(3,0),(4,1),(5,2),(3,3),(6,4),(3,5),(2,6)]   -}

O lado esquerdo do gerador da lista é um padrão.

A lazy evaluation do Haskell faz com que não seja problemático usar uma lista infinita como argumento da função zip.

> posicoes 3 [4,5,3,4,5,6,3,5,3,1]
[2,6,8]

Exemplo: Calcular os divisores de um número positivo.

divisores :: Integer -> [Integer]
divisores n = [ x | x <- [1..n], n `mod` x == 0]

Testar se um número é primo.

primo :: Integer -> Bool
primo n = divisores n == [1,n]

> primo 5
True
> primo 1
False

Lista de números primos até um dado n.

primosAte :: Integer -> [Integer]
primosAte n = [ x | x <- [1..n], primo x]

Lista infinita de números primos.

primos :: [Integer]
primos = [ x | x <- [2..], primo x]