Is there a way to remove a certain type from a Union of types?

Eg. given Union{Int,Float64,String} I want to obtain Union{Int,Float64} by removing String. Is there a way to carry this out?

There is

julia> Core.Compiler.typesubtract(Union{Int,Float64,String}, String)
Union{Float64, Int64}

but as you can see, it is a pretty internal function.

6 Likes

Hi. If there is still interest in the question, this could be an alternative that does not go so deep into internals:

# Matched types return an empty list of types
excludetype(::Type{T}, ::Type{T}) where T = Type[]

# Return a list of subtypes from (maybe) abstract type
# without the excluded one
function excludetype(abstype, excluded)
    st = subtypes(abstype)
    isempty(st) && return [abstype] # no subtypes
    typelist = Type[]
    for T in st
        if excluded <: T
            append!(typelist, excludetype(T, excluded))
        else
            push!(typelist, T)
        end
    end
    return typelist
end

# Same but for unions
function excludetype(U::Union, excluded)
    return [excludetype(U.a, excluded); excludetype(U.b, excluded)]
end

This gives a vector with the filtered list of types that have to be united, and then you can turn it into the filtered Union:

filterfromtype(T, S) = Union{excludetype(T, S)...}

For instance:

julia> filterfromtype(Union{Int,Float64,String}, String)
Union{Float64, Int64}

julia> filterfromtype(Union{Number,String}, Irrational)
Union{AbstractFloat, Integer, String, Complex, Rational}

Is there any way to construct a type that includes everything except for a certain type? Something along the lines of,

T = SetSubtract{Any,MyType}

Then, every type would subtype T except for MyType. I would want this so that MyType can indicate something specifically not to dispatch on (in my case, a singleton type).

2 Likes