Hi, quite new to elixir and type specs; I can’t seem to get the right way of specifying a hashdict. So, this will not work What am I missing? Isn’t a HashDict a Dict and %{} should work? Thanks in advance
defmodule TodoList do
@moduledoc false
defstruct auto_id: 1, entries: HashDict.new
@type todo_list :: %TodoList{auto_id: integer, entries: %{}}
@spec new :: todo_list
def new, do: %TodoList{}
end
It can be difficult or impossible to specify certain types. Erlang terms (including maps), Elixir’s structs, and
remote type definitions like String.t are about as much as you’ll get. In the past I’ve wanted to specify an Enum.t containing only some specified type, but it can’t be parameterized. Somebody else may know more specifics as to why.
Anyway, I haven’t worked with HashDict or Dict much because they’ve both been deprecated in favor of Map and Keyword lists. Perhaps you’d have better luck with one of them. As shown in the typespecs docs, [key: value_type] specifies a keyword list with keys of type key and values of type value_type, and similarly %{key: value_type} represents maps from type key to type value_type. You can get a bit more fancy, but there’s definitely limitations. The docs give a good overview of what is supported.
Minor suggestion: if you intend to later support inserting items into the entries map, you may want to use %{optional(any) => any} instead of %{}. From the docs:
Notice that the syntactic representation of map() is %{optional(any) => any}, not %{}. The notation %{} specifies the singleton type for the empty map.