Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Elixir – possible to combine custom map types?

When defining types in an Elixir module, is it possible to merge two different map types, where one is a subset of the other? For example:

defmodule Test do
  @typep map_a :: %{foo: String.t(), bar: String.t()}
  @typep map_b :: %{foo: String.t(), bar: String.t(), baz: String.t()}
end

I’d like to indicate that the map_b type is a map that is essentially an instance of map_a() plus the additional baz key. I experimented with Map.merge(map_a(), %{baz: String.t}) – that compiles, but when I inspect the types via t(Test), I just get back exactly what I wrote,

@typep map_b :: Map.merge(map_a(), %{baz: String.t})

which doesn’t really give me insight into whether or not this really does what I’m hoping it does.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Is using Map.merge/2 (or anything similar) to combine custom map types a valid approach? If not, how might this be accomplished?

Thanks much.

>Solution :

Map.merge/2 won’t work for specs, it’s not a map actually, it’s just a similar syntax.

One might achieve the desired result with a bit of metaprogramming.

defmodule Test do
  @map_a_type quote(do: [foo: String.t(), bar: String.t()])

  @typep map_a :: %{unquote_splicing(@map_a_type)}
  @typep map_b :: %{unquote_splicing(@map_a_type), baz: String.t()}
end
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading