Skip to content

Instantly share code, notes, and snippets.

@ishikawa
Created October 3, 2016 12:17
Show Gist options
  • Save ishikawa/37d00271b0527d590e4b9c1119b6fab7 to your computer and use it in GitHub Desktop.
Save ishikawa/37d00271b0527d590e4b9c1119b6fab7 to your computer and use it in GitHub Desktop.
Create union type from list
defmodule MyTypespec do
defmacro union_type({:"::", _, [name, types]}) when is_list(types) do
union =
types
|> Enum.reverse
|> Enum.reduce(fn x, acc ->
{:|, [], [x, acc]}
end)
quote do
@type unquote(name) :: unquote(union)
end
end
end
defmodule M1 do
import MyTypespec
@type a :: 1 | 2 | 3
@type foo :: a | :a
union_type foo2 :: [a, :a]
union_type foo3 :: [foo2, :b, 1]
end
IO.inspect Kernel.Typespec.beam_types(M1)
# [type: {:a,
# {:type, 19, :union, [{:integer, 0, 1}, {:integer, 0, 2}, {:integer, 0, 3}]},
# []},
# type: {:foo, {:type, 20, :union, [{:user_type, 20, :a, []}, {:atom, 0, :a}]},
# []},
# type: {:bar2, {:type, 22, :union, [{:user_type, 22, :a, []}, {:atom, 0, :a}]},
# []},
# type: {:bar3,
# {:type, 23, :union,
# [{:user_type, 23, :bar2, []}, {:atom, 0, :b}, {:integer, 0, 1}]}, []}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment