The syntax below is throwing when I pass a List as input. Its always expecting a String.
@spec do_things(String.t()) :: String.t()
def do_things(input) do
String.split(input, "\n")
|> |Enum.map(&(String.graphemes(&1)))
|> do_things()
end
@spec do_things([List]) :: String.t()
def do_things(list) do
#do things and return string
end
Since the compiler will see these as the same function definition you will need to help it by defining under what circumstances each of these should be executed. In Elixir, a guard clause does this. So in your case, for example:
@spec do_things(String.t() | list()) :: String.t()
def do_things(input) when is_binary(input) do
String.split(input, "\n")
|> do_things()
end
def do_things(list) when is_list(list) do
#do things and return string
end
Note that there can only be one @spec since a function is defined by its name and arity and therefore these are both the same function.
What will be spec syntax if I want to return different data types;
for example, one method returns String and another returns a list and another return in an integer.
Understandably a function that has variable return types will be more difficult to compose and probably harder to debug. The case of returning a valid result or an error return wrapped in a tuple like {:error, reason} is idiomatic however.
@spec do_things(String.t()) :: String.t()
def do_things(input) when is_binary(input) do
#do things with string and return string
end
@spec do_things(list()) :: integer
def do_things(list) when is_list(list) do
#do things with list and return integer
end
and @kip, I agree with you, same functions with different return types are difficult to debug. I am pretty new to elixir and just trying out different things for mastering the language
Considering that you’re defining the spec for the same function, that may have different return types, you could define the return type as an union of String.t() | list(integer) | integer.
Just like @kip defined the argument as String.t() | list()
Although, if a function has many different return types it’s a sign that function may be doing too much things, or using a string or integer to indicate error (like an error code or error message) when it could benefit from an ok/error tuple (but that’s another subject).