# UnionAll wrapper not eq anymore to free UnionAll when Type lifted - is it a bug or not?

**URL:** <https://discourse.julialang.org/t/unionall-wrapper-not-eq-anymore-to-free-unionall-when-type-lifted-is-it-a-bug-or-not/74118>\
**Category:** General Usage\
**Tags:** type, parametric-types, dispatch\
**Created:** [January 6, 2022, 2:57am UTC](https://discourse.julialang.org/t/unionall-wrapper-not-eq-anymore-to-free-unionall-when-type-lifted-is-it-a-bug-or-not/74118 "2022-01-06T02:57:57Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)\
**Post date:** [January 6, 2022, 2:57am UTC](https://discourse.julialang.org/t/unionall-wrapper-not-eq-anymore-to-free-unionall-when-type-lifted-is-it-a-bug-or-not/74118/1 "2022-01-06T02:57:57Z")

</div>

Let’s define

```julia
struct A{U,V} end

```

and observe some equalities on data

```julia
using Test

@test A == A{U,V} where {U,V}
@test Type{A} == Type{A{U,V} where {U,V}}

@test A === A{U,V} where {U,V}
@test Type{A} === Type{A{U,V} where {U,V}}

```

they are mapped to equalities on functions with those data instance argument

```julia
f(::A) = :a
@test methods(f) |> length == 1 # clean up your env if needed
@test f(A{:foo,:bar}()) == :a

f(::A{U,V}) where {U,V} = :a_u_v
@test methods(f) |> length == 1
@test f(A{:foo,:bar}()) == :a_u_v

```

But are not mapped to equalities on functions with those data type argument

```julia
F(::Type{A}) = :A
@test methods(F) |> length == 1 # clean up your env if needed

F(::Type{A{U,V}}) where {U,V} = :A_U_V
@test_broken methods(F) |> length == 1
@test_broken methods(F) |> length != 2

```

Shouldn’t they be undistinguished both at instance and type level ?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [January 6, 2022, 3:20am UTC](https://discourse.julialang.org/t/unionall-wrapper-not-eq-anymore-to-free-unionall-when-type-lifted-is-it-a-bug-or-not/74118/2 "2022-01-06T03:20:56Z")

</div>

> [@o314](#):
>
> ```julia
> @test A === A{U,V} where {U,V}
> @test Type{A} === Type{A{U,V} where {U,V}}
> 
> ```

these are not needed, comparison between types is always `===`.

* * *

the two `F` definitions are different, namely:

```julia
julia> F(A)
:A

julia> F(A{Float64, Int})
:A_U_V

```

by having `{U, V}`, you’re demanding the type A to be parameterized instead of left floating, this is basically:

```julia
julia> Vector{Int} == Vector{U} where U
false

```

you can even get more methods by only letting one of the parameters floating:

```julia
julia> F(::Type{A{U,Int}}) where {U} = :A_U_Int
F (generic function with 3 methods)

julia> length(methods(F))
3

```

---

<div class="post-metadata">

**Author:** ![o314](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/o314/32/252_2.png) [@o314](https://discourse.julialang.org/u/o314)\
**Post date:** [January 6, 2022, 5:36am UTC](https://discourse.julialang.org/t/unionall-wrapper-not-eq-anymore-to-free-unionall-when-type-lifted-is-it-a-bug-or-not/74118/3 "2022-01-06T05:36:02Z")

</div>

OK for `===` trivial. Let’s forget it (that was a filler 🙂 )

You specialize thing to `Int` and try to generalize it again but awkwardly. Once you bind it, it’s not the same anymore. That do not follow logical construction. I don’t know what 's “left floating”. `float` @ [More about types · The Julia Language](https://docs.julialang.org/en/v1/devdocs/types/#UnionAll-types) only concerns `Float32` and `Float64`

```julia
@test Vector{Int} != Vector{U} where U # of course
@test Vector{Int} != Vector # and also
@test Vector{Int} <: Vector{U} where U
@test Vector{Int} <: Vector

```

My point was not to demonstrate that you can not define more methods (your len==3), of course you can.  
It is to assert the unicity of the one that is fully unbound. It’s constructed thru an iterated union, so finitely, and must be unique, either at the instance level (done) and at the type level (not already done) since every finite lattice is complete.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [January 6, 2022, 7:35am UTC](https://discourse.julialang.org/t/unionall-wrapper-not-eq-anymore-to-free-unionall-when-type-lifted-is-it-a-bug-or-not/74118/4 "2022-01-06T07:35:17Z")

</div>

> [@o314](#):
>
> left floating

floating as oppose to “fixed”
