Estou tentando dissecar e entender como acc/0
e reducer/0
como funciona dentro do Protocolo Enumerável.
def map(enumerable, fun) do
reducer = fn x, acc -> {:cont, [fun.(x) | acc]} end
Enumerable.reduce(enumerable, {:cont, []}, reducer) |> elem(1) |> :lists.reverse()
end
Alguém poderia explicar isso a partir dos valores de x, acc em cada enumeração
Isso é quase, mas não exatamente como as
Enum.reduce/3
operações de "redução" ou "dobra" de nível superior e semelhantes em outras linguagens funcionais.Enumerable
é um protocolo Elixir de nível inferior (interface) que os tipos podem implementar para dizer que são "um contêiner" e podem ser usados com aEnum
função;reduce
é o alicerce principal.O
reducer
parâmetro será chamado uma vez para cada elemento da lista, com o valor anterior (ou inicial) do acumulador como parâmetro. OEnumerable:acc/0
tipo do parâmetro acumulador inclui não apenas o valor, mas também um átomo de controle que informa àEnumerable
implementação o que fazer, em particular com a opção de parar antecipadamente.:cont
aqui significa "continuar" e, neste exemplo, você sempre percorrerá a lista inteira.Digamos que você ligue
Então a sequência de chamadas internas será
e a lógica restante divide o
:cont
marcador e inverte a lista para que fique na ordem correta.