Destructuring a Union{...}

What is the idiomatic way to take apart a Union type? The obvious structural matching doesn’t do what I expected:

julia> f1(::Type{Union{X, Int64}}) where {X} = X
f1 (generic function with 1 method)

julia> f1(Union{Int64, Float64})
Float64

julia> f2(::Type{Union{X, Float64}}) where {X} = X
f2 (generic function with 1 method)

julia> f2(Union{Int64, Float64})
Int64

julia> f3(::Type{Union{X, Y}}) where {X, Y} = (X, Y)
f3 (generic function with 1 method)

julia> f3(Union{Int64, Float64})
ERROR: UndefVarError: Y not defined
Stacktrace:
 [1] f3(::Type{Union{Float64, Int64}}) at ./REPL[7]:1
 [2] top-level scope at none:0
1 Like

Huh, what ends up happening is that X matches Union{Float64, Int64} and Y is left undefined. I wonder if this is a bug.

I also wonder if there’s a way to use something like where X >: Union{} to constrain both X and Y to match something (this doesn’t work because Union{} >: Union{}).

Not a bug (https://github.com/JuliaLang/julia/issues/28674#issuecomment-413351095), but it certainly means that my mental model of unification is wrong. I guess matching is greedy?

1 Like