I have defined an Elixir behaviour X
. A callback start_link
is spec'ed as:
@callback start_link(
args :: producer_args,
opts :: GenServer.options
) :: GenServer.on_start
where producer_args
type is defined as:
@type producer_args :: %{job_queue_name: String.t}
In the client code Y
that implements the behaviour, start_link
is defined as:
def start_link(args = %{job_queue_name: _job_queue_name, redis_url: _redis_url}, opts) do
GenStage.start_link(__MODULE__, args, opts)
end
Dialyzer doesn't like it. It says,
(#{'job_queue_name':=_, 'redis_url':=_, _=>_})
is not a supertype of
#{'job_queue_name':=binary()}
Question #1:
In terms of inheritance, subtypes extend supertypes. Therefore, the defined behaviour(X) should be considered supertype. Module implementing the behaviour(Y) should be considered subtype. Apparently Dialyzer should have asked the question:
Is
#{'job_queue_name':=binary()}
a supertype of(#{'job_queue_name':=_, 'redis_url':=_, _=>_})
?
Rather it asks the question the other way around. Why?
Question #2:
Is the definition of supertype
in dialyzer the same as in discussion of OOP inheritance? If not, what is it then? I tried to find definition of supertype in the context of dialyzer but found none.
redis_url
property, dialyzer is happy. So,binary
vsany
is not the problem. – Obscenity