I have a function, and its definition is shown below:
def my_func(%{a: %{b: _}}) do
"output"
end
def my_func(_) do
nil
end
when the input of myfunc is nested map with the key a.b, the output will be a string, or the output will be nil.
then I try to add type spec for it like below:
@spec my_func(%{a: %{b: any()}}) :: String.t()
@spec my_func(any()) :: nil
def my_func(%{a: %{b: _}}) do
"output"
end
def my_func(_) do
nil
end
But I receive overlapping_contract error after executing mix dialyzer
. Now I’m wondering if there is a feature which can indicate the exclude type so I can add type spec like below:
@spec my_func(%{a: %{b: any()}}) :: String.t()
@spec my_func(not(%{a: %{b: any()}})) :: nil
def my_func(%{a: %{b: _}}) do
"output"
end
def my_func(_) do
nil
end
And of course if I just declare the input as any():
@spec my_func(any()) :: String.t() | nil
def my_func(%{a: %{b: _}}) do
"output"
end
def my_func(_) do
nil
end
I can easily pass the mix dialyzer
. But I think the method make the type checking meaningless, because it doesn’t actually check anything, all the types of the input is OK.