Record documentation mentions special record/2 macro for use in typespecs only:
Types can be defined for tuples with the record/2 macro (only available in typespecs).
But I can’t find source code of this macro.
I write Record-like module and I need to write a macro to generate typescpecs.
But I don’t understand how to write a macro that would work in typespecs.
defmodule TypespecMacro.Util do
defmacro deftype(name, spec) do
quote do
@type unquote(name) :: unquote(spec)
end
end
end
defmodule TypespecMacro do
import TypespecMacro.Util
deftype(type1, any)
deftype(type2, any)
@spec foo(type1, type2) :: {type1, type2}
def foo(arg1, arg2) do
{arg1, arg2}
end
end
$ iex -S mix
Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> h TypespecMacro.foo
def foo(arg1, arg2)
@spec foo(type1(), type2()) :: {type1(), type2()}
defmodule TypespecMacro.Util do
defmacro defspec(fields) do
quote do
# generating spec based on fields
end
end
end
defmodule TypespecMacro do
import TypespecMacro.Util
@type t() :: defspec(field1: integer(), field2: String.t())
end
I already did it in the same way as in your example. Awkward, but works.
Well, if you wanted to define in my example a type of arity > 0 you wouldn’t have been able to do it.
By arity i mean, that it takes let’s say one argument. @type my_type(any) :: {:ok, any()}