defmodule Unionex do
defmacro unionex(types) do
ast_to_list(types)
end
def ast_to_list(atom) when is_atom(atom) do
[atom]
end
def ast_to_list({:|, _, [atom, rest]}) do
[atom | ast_to_list(rest)]
end
end
In the console:
Interactive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> import Unionex
Unionex
iex(2)> unionex(:x | :y | :z)
[:x, :y, :z]
Macros take AST and return AST. If the return isn’t valid AST you’ll get a compile error. It so happens that a list of atoms is valid AST which is why returning the list works in this example. In practise if your list isn’t valid AST then you would need to process it into valid AST.
There is some discussion on the core mailing list about implementing some kind of construct to convert a list to a typespec so in the future maybe this will be more straight forward.