# Deconstructing UnionAll types

**URL:** <https://discourse.julialang.org/t/deconstructing-unionall-types/108328>\
**Category:** General Usage\
**Created:** [January 4, 2024, 4:11am UTC](https://discourse.julialang.org/t/deconstructing-unionall-types/108328 "2024-01-04T04:11:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)\
**Post date:** [January 4, 2024, 4:11am UTC](https://discourse.julialang.org/t/deconstructing-unionall-types/108328/1 "2024-01-04T04:11:33Z")

</div>

The following naive definition is invalid, but you don’t realize it until you try it:

```julia
julia> f(::Type{Set{<:W}} where W) = W
f (generic function with 4 methods)

```

Here goes…

```julia
julia> f(Set{<:Integer})
ERROR: UndefVarError: `W` not defined

```

I can get the functionality I wanted with a hack:

```julia
julia> f_hack(t::Type{Set{<:W}} where W) = t.var.ub
f_hack (generic function with 1 method)

julia> f_hack(Set{<:Integer})
Integer

```

So how do I do this with public API?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [January 4, 2024, 6:11am UTC](https://discourse.julialang.org/t/deconstructing-unionall-types/108328/2 "2024-01-04T06:11:04Z")

</div>

> [@ablaom](#):
>
> `f(::Type{Set{<:W}} where W) = W`

I think you wanted to put the parenthesis before the `where`, otherwise `W` is not a parameter of the method, so it can’t be defined in the method body.

Furthermore, the `<:` doesn’t really make sense there, because it doesn’t allow to unambiguously derive a value for `W`.

Setting all that aside, it seems that your goal is to find the upper bound for one of the parameters of a UnionAll type? I’m pretty sure that’s not supported, and it also doesn’t seem like something that should be supported. Is there a higher-level problem that lead you to this question?

---

<div class="post-metadata">

**Author:** ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)\
**Post date:** [January 4, 2024, 7:41pm UTC](https://discourse.julialang.org/t/deconstructing-unionall-types/108328/3 "2024-01-04T19:41:37Z")

</div>

Thanks @nsako for your reply.

> I think you wanted to put the parenthesis before the `where` , otherwise `W` is not a parameter of the method, so it can’t be defined in the method body.

Ok, but I still get an error:

```julia
julia> f(::Type{Set{<:W}}) where W = W
f (generic function with 1 method)

julia> f(Set{<:Integer})
ERROR: UndefVarError: `W` not defined

```

> Furthermore, the `<:` doesn’t really make sense there, because it doesn’t allow to unambiguously derive a value for `W` .

Right, I can see that.

> Setting all that aside, it seems that your goal is to find the upper bound for one of the parameters of a UnionAll type?

Yes, that’s what I want.

> it also doesn’t seem like something that should be supported.

Why not?

> Is there a higher-level problem that lead you to this question?

I’m wanting to do something like this: I have a class of objects, let’s say they are all callable, and a trait `input_type(object)` with the property that `object(x)` is defined whenever `typeof(x) <: input_type(object)`. These objects are defined in some third party package and I want to introduce a new trait for these objects `output_type(object)` which is to have the property `typeof(object(x)) <: output_type(object)` for all valid `x` (ones satisfying `typeof(x)) <: input_type(object)`). I have insight into the package to say things like: if `input_type(object) = Set{<:Integer}` then an appropriate definition of `output_type(object)` is `Vector{<:Integer}`, but don’t know how to articulate this latter insight to write a definition of the derived `output_type` trait.
