Hello, I would like to dispatch on the Union type, if I explicitly write it down, it works:
julia> T = Union{<:Number, Ref{<:Number}}
Union{Ref{#s13} where #s13<:Number, #s12} where #s12<:Number
julia> f(x::T, y::T) = "ok"
f (generic function with 1 method)
julia> f(1, Ref(1))
"ok"
However, if I use the subtypeing gramma:
julia> g(x::U, y::U) where {U <: T} = "ok"
g (generic function with 1 method)
julia> g(1, Ref(1))
ERROR: MethodError: no method matching g(::Int64, ::Base.RefValue{Int64})
Closest candidates are:
g(::U<:(Union{Ref{#s13} where #s13<:Number, #s12} where #s12<:Number), ::U<:(Union{Ref{#s13} where #s13<:Number, #s12} where #s12<:Number)) where U<:(Union{Ref{#s13} where #s13<:Number, #s12} where #s12<:Number) at REPL[8]:1
Stacktrace:
[1] top-level scope at none:0
I thought both arguments should fit in the type:
julia> Ref(1)::T
Base.RefValue{Int64}(1)
julia> 1::T
1
julia> T <: T
true
This is the diagonal rule (should be mentioned in the manual):
f(x::T, y::T) where T = 1
only ever works if typeof(x)==typeof(y). Only after this check a possible subtype check on T is done. Example:
julia> f(x::T, y::T) where T<:Integer = 1
f (generic function with 1 method)
julia> f(5,6)
1
julia> f(5,UInt(6))
ERROR: MethodError: no method matching f(::Int64, ::UInt64)
Closest candidates are:
f(::T<:Integer, ::T<:Integer) where T<:Integer at REPL[1]:1
Stacktrace:
[1] top-level scope at none:0