Background
I am reading Designing Elixir Systems with OTP and while coding the examples I am trying to add dialyzer specs.
Now, one recent issue I find, is that no matter what, Dialyzer will complain about a spec I have. I am very very convinced dialyzer is actually wrong, which shouldn’t be a thing.
Code
Following is the code. I define a type called quiz_info
which is a fancy map. Then I have 2 private functions that start quizzes.
@type quiz_info :: %{
fields: map,
templates: [keyword],
start_at: DateTime.t,
end_at: DateTime.t
}
# Divides ready to start quizzes from not ready to start ones. Starts the quizzes that are ready
# and returns the ones that are not.
@spec start_quizzes([quiz_info], DateTime.t) :: [quiz_info]
defp start_quizzes(quizzes, now) do
{ready, not_ready} = Enum.split_while(quizzes, fn quiz ->
date_time_less_than_or_equal?(quiz.start_at, now)
end)
Enum.each(ready, &start_quiz(&1, now))
not_ready
end
# starts a quizz. Sends a message to itself once a quizz time is up.
@spec start_quiz(quiz_info, DateTime.t) :: reference
defp start_quiz(quiz, now) do
QuizManager.build_quiz(quiz.fields)
Enum.each(quiz.templates, &add_template(quiz, &1))
timeout =
quiz.end_at
|> DateTime.diff(now, :millisecond)
|> time_to_finish()
Process.send_after(self(), {:end_quiz, quiz.fields.title}, timeout)
end
So, my main function start_quizzes
receives a list of quiz_info
and a date, and returns a list of quiz_info
.
Dialyzer doesn’t complain here. But it complains on the next one, start_quiz
.
Error
The @spec for the function does not match the success typing of the function.
Function:
Mastery.Boundary.Proctor.start_quiz/2
Success typing:
@spec start_quiz(atom(), %DateTime{
:calendar => atom(),
:day => pos_integer(),
:hour => non_neg_integer(),
:microsecond => {char(), 0 | 1 | 2 | 3 | 4 | 5 | 6},
:minute => non_neg_integer(),
:month => pos_integer(),
:second => non_neg_integer(),
:std_offset => integer(),
:time_zone => binary(),
:utc_offset => integer(),
:year => integer(),
:zone_abbr => binary()
}) :: reference()
According to dialyzer, my start_quiz
function which receives a quiz_info
should be receiving a atom
. I have no idea where this comes from.
Question
What am I missing?