Dialyzer not analyzing all code paths for type checking

Hello all. I’m having an issue where dialyzer does not completely verify that all code paths of a function returns the type specified by @callback. Below are the typespecs.

@callback goodNumber?(number) :: goodNumber | badNumber
@type goodNumber :: {:ok, number}
@type badNumber :: {:error,number}

And here is the function

  def goodNumber?(num) do
if(num > 100) do
  {"asdf",num}
else
  {:error,num}
end
end

Despite goodNumber? possibly returning {“asdf”,num}, which does not match neither goodNumber nor badNumber, dialyzer passes. Dialyzer fails only when all possible code paths do not return the specified type. Are there any ways to modify the behavior of dialyzer to more stringently check @callback specs? Thank you.

You can do it like this

@callback goodNumber?(number) :: goodNumber | badNumber
@type goodNumber :: {:ok, number}
@type badNumber :: {:error,number}
def goodNumber?(num) do
  if(num > 100) do
    goodAnswer(num)
  else
    badAnswer(num)
  end
end

@spec goodAnswer(number()) :: goodNumber()
def goodAnswer(num), do: {:ok, num}

@spec badAnswer(number()) :: badNumber()
def badAnswer(num), do: {:error, num}

You can also replace if with

def goodNumber?(num) when num > 100, do: goodAnswer(num)
def goodNumber?(num), do: badAnswer(num)
3 Likes