Erlang (Elixir) Dialyzer - confusing supertype error

I determined the behavior of the elixir X. The callback is start_linkspecified as:

@callback start_link(
  args :: producer_args,
  opts :: GenServer.options
) :: GenServer.on_start

where the producer_argstype is defined as:

@type producer_args :: %{job_queue_name: String.t}

In client code Ythat implements behavior, it start_linkis 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

The dialyzer does not like this. It says:

(#{'job_queue_name':=_, 'redis_url':=_, _=>_}) 
is not a supertype of 
#{'job_queue_name':=binary()}

Question number 1:

In terms of inheritance, subtypes extend supertypes. Therefore, certain behavior (X) should be considered a supertype. A module that implements behavior (Y) should be considered a subtype. Apparently, Dilizer should have asked a question:

Is it a #{'job_queue_name':=binary()}supertype (#{'job_queue_name':=_, 'redis_url':=_, _=>_})?

Rather, he asks a different question. Why?

Question number 2:

supertype , ? , ? , .

+4
2

: redis_url, spec .

Dialyzer . .

, #{'job_queue_name':=_, 'redis_url':=_, _=>_}, , #{'job_queue_name':=_}.

So #{'job_queue_name':=_, 'redis_url':=_, _=>_} #{'job_queue_name':=_}.

Dialyzer , , , , , , .

+6

:

: NO.

. Erlang/Elixir ( - , ! receive ), . Succes Dialyzer.

paper. talk .

, , . , , , , , , . , , , , .

:

  • , . .
  • . add, . (bool(), bool()), - (any(), any()) (false, any()) | (any(), false) | (true, true). , , .
  • typer, , dialazer .
+4

Source: https://habr.com/ru/post/1685775/


All Articles