Background
I have a multiclause function and I want to use @spec
. I am aware of two ways I can do it, but I don’t know which way is the most correct.
Code
defp get_country({:ok, [country | _tail]}, _ip), do: String.upcase(country)
defp get_country({:error, reason}, ip) do
Logger.error("Error Geolocating #{inspect ip} -> #{inspect reason}")
nil
end
Using Spec
I know of 2 ways to use @spec
that wont make dialyzer throw errors:
Option 1:
@spec get_country({:ok, [String.t]} | {:error, any}, String.t) :: String.t | nil
defp get_country({:ok, [country | _tail]}, _ip), do: String.upcase(country)
defp get_country({:error, reason}, ip) do
Logger.error("Error Geolocating #{inspect ip} -> #{inspect reason}")
nil
end
Option 2:
@spec get_country({:ok, [String.t]}, String.t) :: String.t
defp get_country({:ok, [country | _tail]}, _ip), do: String.upcase(country)
@spec get_country({:error, any}, String.t) :: nil
defp get_country({:error, reason}, ip) do
Logger.error("Error Geolocating #{inspect ip} -> #{inspect reason}")
nil
end
Question
Which way is the correct way?
If they are both correct, which way is the most idiomatic/preferred?