Hello! I have a question about @spec for functions with multiple clauses. Should there be one @spec definition for each function/arity? Or should there be a @spec for each function declaration?
For example is this desireable?
@spec foo({atom, any}) :: any
def foo({:ok, x}), do: x
def foo({:good, x}), do: x
def foo({:error, x}), do: x
or is this better?
@spec foo({:ok, any}) :: any
def foo({:ok, x}), do: x
@spec foo({:good, any}) :: any
def foo({:good, x}), do: x
@spec foo({:error, any}) :: any
def foo({:error, x}), do: x
Most tools expect a single @spec per function at a particular arity.
That said, the most specific typespec that still covers all your inputs is usually the most useful one. Thus, you might want to use @spec foo({:ok | :good | :error, any}) :: any (as @Eiji already mentioned) ,
or, for this particular example even @spec foo({:ok | :good | :error, type}) :: type when [type: any] that indicates that the result value will be of the same type as the value passed in.