Method ambiguity for unions

I have hit the following problem already several times:

ERROR: MethodError: f(::Int64, ::Int64) is ambiguous. Candidates:
  f(x::Union{Float64, Int64}, y::Int64) in Main at REPL[4]:1
  f(x::Int64, y) in Main at REPL[3]:1
Possible fix, define
  f(::Int64, ::Int64)

but I do not understand the reason behind this behavior.

I would expect f(x::Union{Float64, Int64}, y::Int64) to be more specific than f(x::Int64, y) as mentally f(x::Union{Float64, Int64}, y::Int64) can be rewritten as two identical separate definitions f(x::Int64, y::Int64) and f(x::Float64, y::Int64).

Could someone please explain me the reason for the current behavior? Thank you.

You just have two definitions:

  1. f(x::Union{Float64, Int64}, y::Int64)
  2. f(x::Int64, y)

When you call f(x::Int, y::Int), method 2 is more specific for x but method 1 is more specific for y. Thus the ambiguity.


Thank you. I understand this point, and of course f(x::Union{Float64, Int64}, y::Int64) has still to be ambiguous with f(x::Int64, y::Union{Float64, Int64}) for two Ints passed.

My thinking was that when you have an ambiguity over an union vs ambiguity over an an abstract type then we could have a precedence defined over them (but I guess then the dispatch rules would get overly complex).