My advice would be to put the case statement in its own function.
You can make it an inline function like @LostKobrakai suggests, but your code will become more readable if you put it in its own named function, especially since this also allows you to get rid of the case and just use pattern-matching at the function level:
I agree that putting the case in a function is the prettiest, but to answer the actual question as it was asked, the problem with this:
is that the “catch all” branch of the case has the value assigned to “_”, which is the “ignore this value” variable name (well … anything starting with an _, really). So there is no variable to bind. It should be something like:
Note how now the 2nd case branch is capturing the value into the loc variable … and now it can be used
If you really want to keep this, using an anonymous function, you need to remember that you can pattern match in them multiple times as well.
So the following should do what you want:
foo
|> Enum.map(fn
[x] -> x
[] -> []
end)
This will convert [[], [:a]] into [[], :a], [[], []] into [[], []] and [[:foo], [:bar]] into [:foo, :bar] which seems to be what you want from your first post.
PS: It might be, that Enum.concat/1 does pretty well what you need, also one could perhaps use Enum.flat_map/2: foo |> Enum.flat_map(&(&1)) (both filter out the empty lists though).