traverse
transforma as coisas dentro de uma Traversable
em uma Traversable
das coisas "dentro" de uma Applicative
, dada uma função que faz Applicative
s das coisas.
Vamos usar Maybe
como Applicative
e listar como Traversable
. Primeiro, precisamos da função de transformação:
half x = if even x then Just (x `div` 2) else Nothing
Portanto, se um número for par, obtemos metade dele (dentro de a Just
), caso contrário, obtemos Nothing
. Se tudo correr "bem", será assim:
traverse half [2,4..10]
--Just [1,2,3,4,5]
Mas...
traverse half [1..10]
-- Nothing
O motivo é que a <*>
função é usada para construir o resultado, e quando um dos argumentos é Nothing
, nós o obtemos Nothing
.
Outro exemplo:
rep x = replicate x x
Esta função gera uma lista de comprimento x
com o conteúdo x
, por exemplo rep 3
= [3,3,3]
. Qual é o resultado de traverse rep [1..3]
?
Nós obter os resultados parciais de [1]
, [2,2]
e [3,3,3]
usando rep
. Agora a semântica de listas como Applicatives
é "tomar todas as combinações", por exemplo, (+) <$> [10,20] <*> [3,4]
é [13,14,23,24]
.
"Todas as combinações" de [1]
e [2,2]
são duas vezes [1,2]
. Todas as combinações de duas vezes [1,2]
e [3,3,3]
são seis vezes [1,2,3]
. Então nós temos:
traverse rep [1..3]
--[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]