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?