Made a typo, but Elixir did not complain. Dialyzer gave me a headache though. What does this syntax mean?
@spec handle_response({:ok, term()} | {:error, term()}, ({:ok, term()} -> term())) ::
term() :: {:error, String.t()}
What I really wanted was term() | {:error, String.t()}
.
1 Like
After a few experiments
@spec handle_response({:ok, term()} | {:error, term()}, ({:ok, term()} -> term())) ::
term() :: {:error, String.t()}
seems to simply mean
@spec handle_response({:ok, term()} | {:error, term()}, ({:ok, term()} -> term())) :: {:error, String.t()}
So it seems that the second ::
simply narrows the type of term()
to {:error, String.t()}
.
I tried:
-
@spec main([binary()]) :: :ok
as the starting “correct” function specification.
-
@spec main([binary()]) :: term() :: :ok
still passed.
-
@spec main([binary()]) :: :ok :: term()
failed compilation.
-
@spec main([binary()]) :: term() :: :ok
failed dialyzer when the function returned :off
instead of :ok
.
-
@spec main(binary()) :: r when r: term() :: :ok
passes.
-
@spec main(binary()) :: term() :: r when r: :ok
passes.
-
@spec main(binary()) :: atom() :: :ok
passes.
2 Likes