# Specs for overloaded function

As I couldn’t find a good example in the docs, Elixir and Ecto repository, I’m going to post the question here. I wasn’t able to find the error documented somewhere either.

I’m trying to write specs for a set of functions that serve one goal: calculating a cumulative moving average.

The code for generating the CMA looks like the following:

``````  def cumulative([]) do
nil
end

def cumulative(list)
when is_list(list) do
cumulative(0, 0, list)
end

def cumulative({weight, avg}, list)
when is_integer(weight) and is_list(list) do
cumulative(weight, avg, list)
end

def cumulative(0, _, []) do
nil
end

def cumulative(weight, average, []) do
{weight, average}
end

def cumulative(weight, average, [hd | tl], results \\ [])
when is_integer(weight) and is_number(hd) do
new_weight = weight + 1
new_avg = (average * weight + hd) / new_weight

case tl do
[_ | _] ->
cumulative(new_weight, new_avg, tl, results ++ [new_avg])
[] ->
{new_weight, results ++ [new_avg]}
end
end
``````

After trying to add specs above the functions:

``````  @spec cumulative(list) :: {integer,  float}
when list: [float] | [integer]
@spec cumulative(tuple, list) :: {integer,  float}
when tuple: {integer, integer | float},
list: [float] | [integer]
``````

I get the following error:

type variable tuple is only used once (is unbound)

I must be doing something wrong. How do I add specs correctly?

I think this is quite a misleading error message, because of `tuple/0` beeing a predefined type, after I have switched it by `t`, it worked without an error message for me.

You should avoid `list` as well, it is a built-in type as well. In generall, try to avoid those basic types of erlang and elixir as names of own types or variables in a spec.

1 Like