Vamos agora usar o conceito de listas infinitas para descrever a lista de numeros primos.sem_divisor n [ ] = Truesem_divisor n (x:xs) = if (mod n x) == 0 then False else sem_divisor n xs----primos = 2:[x|x<-[3,5 ..], sem_divisor x(takeWhile(<= truncate (sqrt( fromIntegral x)) )primos) ]A elegancia da descricao da lista de primos e o que ha de mais importante, principalmente por usar a propria definicao de primos. Temos aqui a descricao recursiva de uma lista infinita e, portanto, uma recursao infinita. Ou sejam, nossa lista de candidatos a primos sao os numeros imparesx<-[3,5 ..] e para estes verificamos a existencia de divisores, usando para isto apenas um pedaco da lista de primos, ou seja, aqueles que sao menores que a raiz quadrada do numero considerado.(takeWhile (<= truncate (sqrt (fromIntegral x)))primos)Sabemos que a lista primos e infinita e que portanto nao e conveniente a sua avaliacao por completo, entretanto podemos desejar obter os n primeiros numeros primos o que pode ser obtido com o uso de take n.> take 10 primos[2,3,5,7,11,13,17,19,23,29](6948 reductions, 10214 cells)> take 100 primos[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541](174196 reductions, 248654 cells)> take 100 primos[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541](2437 reductions, 3620 cells)E importante observar que na segunda vez que usamos > take 100 primos, o numero de reducoes e bem menor, em decorrencia da abordagem que o interpretador da a avaliacao de uma expressao, guardando os resultados de expressoes para usos posteriores. Varios exemplos apresentados na literatura produzem, com o foldl, elementos simples, como um numero. Mas tambem podemos produzir listas. No exemplo a seguir, desejamos produzir, a partir de uma lista xs, uma lista com o quadrado de cada numero de xs. A funcao quadaux opera produzindo uma nova lista, acrescentando ao final da lista xs o quadrado do numero x dado, usando a operacao "++" para concatenar duas listas. Primeiro produzimos uma lista com o quadrado do numero dado e depois concatenamos. quadaux xs x= xs ++ [x * x] A funcao lquad aplica a funcao quadaux a cada elemento da lista de entrada xs, tendo como elemento neutro a lista vazia. lquad xs = foldl quadaux [ ] xs Vejamos a aplicacao da funcao usando o ambiente HUGS >lquad [1..10][1,4,9,16,25,36,49,64,81,100] > lquad [][] Muito bem, sabemos que os numeros feios podem ser gerados diretamente, sem precisar usar o processo "gerar e testar", como acontece nos numeros primos.qfeios = 1:[ x*y| x <- qfeios, y<-[2,3,5]] e vejamos uma avaliacao, acessando alguns feios:>take 52 qfeios[1,2,3,5,4,6,10,6,9,15,10,15,25,8,12,20,12,18,30,20,30,50,12,18,30,18,27,45,30,45,75,20,30,50,30,45,75,50,75,125,16,24,40,24,36,60,40,60,100,24,36,60](1584 reductions, 2636 cells)Tres aspectos desta lista merecem atencao:a) ela e formada por sublista, cada uma associada com um dos fatores;b) a lista possui elementos repetidos;c) a lista esta desordenada;Os fatos b e c, inviabilizam a determinacao do i-esimo numero feio. Entretanto o fato a no traz uma solucao. Podemos gerar as tres listas isoladamente.m2 = [x*2| x <- feios]m3 = [x*3| x <- feios]m5 = [x*5| x <- feios]e o truque final :feios = 1: merge (merge m2 m3) m5podemos agora, como em qualquer lista infinita, obter sublistas finitas.> take 10 feios[1,2,3,4,5,6,8,9,10,12]> drop 90 (take 100 feios)[1200,1215,1250,1280,1296,1350,1440,1458,1500,1536]e agora voltemos a nossa questao inicial: Determinar o feio de ordem 1500.> head (drop 1499(take