Problema 1 : Dada uma lista xs, descreva a sublista de xs formada apenas por números pares:
fp xs y = xs ++ (if mod y 2 == 0 then [y] else [])
Main> pares [6, 5, 3, 512, 9, 308, 124]
[6,512,308,124]
observe que o elemento final é obtido pela construção de uma lista que usa a lista obtida na interação anterior e o resultado de operar o elemento da lista de entrada com um um valor interior, neste caso a constante 2.
Um trace da execução:1) foldl fp [ ] [6, 5, 3, 512, 9, 308, 124]
2) foldl fp [ 6] [5, 3, 512, 9, 308, 124]
3) foldl fp [ 6] [5, 3, 512, 9, 308, 124]
4) foldl fp [ 6] [3, 512, 9, 308, 124]
5) foldl fp [ 6] [512, 9, 308, 124]
6) foldl fp [ 6, 512] [9, 308, 124]
7) foldl fp [ 6, 512] [308, 124]
8) foldl fp [ 6, 512, 308] [124]
9) foldl fp [ 6, 512, 308, 124] [ ]
Se aplicarmos a função pares a intervalos de números inteiros podemos obter a sublista de números pares pertencentes ao intervalo.
por exemplo,
Main> pares [1..10]
[2,4,6,8,10]
Problema 2 :Desejamos obter a sublista de xs formada pelos elementos de xs que são divisíveis por um dado valor v.
divisiveis v ls = foldl fd ( [], v) ls
fd (xs,v) y = (xs ++ (if mod v 2 == 0 then [y] else []), v)
([3,6,9,12,15,18]
A função define um par, com o resultado mesmo e um dado de entrada que foi incorporado.
where
fd xs y = xs ++ (if mod y v == 0 then [y] else [])
e veja o que podemos obter:
Main> divisiveis' 3 [1..50]
[3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48]
Uma outra observação importante.
A função foldl, opera sobre todos elementos da lista, ainda que não estejamos interessados, ou seja, não temos como explicitar que desejamos interromper o processamento da lista ls, informada em foldl f x xs.
Vejamos um novo exemplo que ilustra a situação.
Problema 3: Desejamos descobrir o preço de um produto p em uma determinada lista de pares (produto, preço).
Ainda que saibamos que cada produto ocorre apenas uma vez na lista, não temos como descrever esta informação.
Assim, não temos como dizer diretamente que ao encontrar o produto na lista desejamos interromper a busca e retornar este valor. Da mesma forma, não temos como guardar este valor diretamente, apesar de podermos incorporar informação do elemento que é atualizado em um ciclo e que serve de entrada para o próximo.
Solução 1
pegapreco x xs = foldl app (0,x,True) xs
app (r,p,controle) (c,preco) = if controle
then if p == c then (preco, p, False)
else (r,p,controle)
else (r,p,controle)
Solução 2
---- solucao sem controle, usando lista
--
pegapreco' x xs = foldl app' ([],x) xs
app' (rs,p) (c,preco) = (rs ++ (if p == c then [preco] else []),p)
([5],"cafe")
Main> pegapreco' "nada"
[ ("nada1",50),("nada2",85),("nada3",35),("cafe",5),("nada4",25),("nada5",15)]
([],"nada")
Main> pegapreco' "nada1" [ ("nada1",50),("nada2",85),("nada3",35),("cafe",5),("nada4",25),("nada1",15)]
([50,15],"nada1")