Hello.
I have piece of code that creates a permutation of a list. I first implemented this using an example I found that uses list comprehensions. This version works, but I wanted to really understand how this works under the hood. I implemented a second version that uses Enum.map and Enum.concat that produces equivalent output to the list comprehension version. However, I wasn’t happy with this version because to make it work, I have to implement two named functions to handle the permutation. I attempted (many times) to create a version that uses only one named function to produce the desired output and always run into problems. The specific problem I am having now is that it seems anonymous functions, as passed as an argument to Enum.map do not receive the second argument. However, if I use basically the same code but with a capture to the named function, instead of the anonymous function, the second argument gets passed along. I find this behavior confounding and am hopeful that someone will be able to help me understand it. Annotated code examples below.
Thanks!
def permute([]), do: [[]]
# List Comprehension version
def permute(list) do
for x <- list, y <- permute(list -- [x]) do [x|y] end
end
# Equivalent to List Comprehension version, only using Enum.map and Enum.concat
def permute(list) do
Enum.map(list, &(permute_inner(&1, list)))
|> Enum.concat()
end
defp permute_inner(x, list) do
permute(list -- [x])
|> Enum.map(&([x|&1]))
end
# Logically equivalent to Enum.map variant above, removes the need for inner_permute.
# Compiles, but list does not get passed in.
def permute(list) do
Enum.map(list, fn(x, list) -> permute(list -- [x]) |> Enum.map(&([x|&1])) end)
|> Enum.concat()
end