Can we import types and guards from another module?

Given this module:

defmodule A do
  @type size :: pos_integer()
  defguard is_size(x) when is_integer(x) and x > 0
  def default_size(), do: 1
end

…how do we make the below work without prefixes?

defmodule B do
  @type t :: %__MODULE__{size: size()}
  defstruct [size: default_size()]
  def put_size(opts, size) when is_list(opts) and is_size(size), do: Keyword.put(opts, :size, size)
end

Tried import A and require A, both don’t get the job done.

What elementary Elixir lesson I managed to forget?

4 Likes

You should be able to import is_size/1 just by doing import A(, only: [is_size: 1]).

You can not import types though. The easiest way is to just alias them.

@type foo :: Foo.foo
14 Likes

Yeah. I just import the guards and prefix the types. Seems there’s no actual seamless way to import everything in one go without any prefixes. Thank you.

You might also group your types into a module like so


defmodule MyApp.Types do

    defmacro __using__(_opts) do 
          quote do
             @type greek_t :: :alpha | :beta
             @type mystruct_t :: MyApp.MyStruct.t # Beware of circulars here!!
          end
    end
...
7 Likes