How to dispatch on an array of T or Union{Nothing,T} but not nothing


#1

I am looking for a concise way to match an AbstractArray of T or Union{Nothing,T} but not Nothing. Does anyone have any ideas how to do that?

The general test I have been using is the following, with the ideal result being [true,true,false]:

julia> test_cases=[AbstractArray{Union{Nothing,Float64},<:Any},
                   AbstractArray{Float64,<:Any},
                   AbstractArray{Nothing,<:Any} ];

julia> typetest(T3)=((T1,T2)->T1<:T2).(test_cases,[T3]);

julia> typetest(AbstractArray{Union{Float64,Union{Nothing,Float64}},<:Any})
3-element BitArray{1}:
  true
 false
 false

julia> typetest(AbstractArray{T,<:Any} where T<:Union{Float64,Union{Nothing,Float64}})
3-element BitArray{1}:
 true
 true
 true

julia> typetest(AbstractArray{T,<:Any} where T<:Union{Nothing,Float64})
3-element BitArray{1}:
 true
 true
 true

julia> typetest(Union{AbstractArray{Float64,<:},AbstractArray{Union{Nothing,Float64}},<:Any})
3-element BitArray{1}:
 true
 true
 true

I think that the first case might be a bug, does anyone have any idea why it gives that result?


#2
f(::AbstractArray{T,<:Any}) where T = println("$T only")
f(::AbstractArray{Union{T, Nothing},<:Any}) where T = println("$T and Nothing")
f(::AbstractArray{Nothing,<:Any}) = println("Nothing only")
julia> f([1,2,3])
Int64 only

julia> f([1, nothing, 3])
Int64 and Nothing

julia> f([nothing, nothing, nothing])
Nothing only

#3

You don’t need ,<:Any


#4

So the signature that matches is:AbstractArray{Union{Float64,T}} where T<:Nothing…matching AbstractArray{Float64} , AbstractArray{Union{Float64,Nothing}}, but not AbstractArray{Nothing}.

But could someone explain why that matches the first two cases?
While AbstractArray{T} where T<:Union{Float64,Nothing} matches all three cases?
And AbstractArray{Union{Float64,Nothing}} only matches the first one?