# Tricky parametric type dispatch

I would like to dispatch a method like this, where `T` gets the type `<: AbstractParticles` and the type parameters end up in `F` and `NT`.

``````function Base.union(p1::T{F,NT},p2::S{F,NS}) where T <: AbstractParticles where S <: AbstractParticles{F,NS} where F where NT where NS
T{F,NT+NS}([p1.particles; p2.particles])
end
``````

This does not work and an error

``````TypeError: in Type{...} expression, expected UnionAll, got TypeVar
``````

occurs. The following definition is accepted, but it makes `T` include the type parameters `T{F,NT}` which I do not want.

``````function Base.union(p1::T,p2::S) where T <: AbstractParticles{F,NT} where S <: AbstractParticles{F,NS} where F where NT where NS
@show T
end
julia> union(p,p)
#T = Particles{Float64,1000}
``````

Is there another way to express the former, or to strip `Particles{Float64,1000}` from the type parameters without using `eval`?

Edit:
The following works, but feels like a hack

``````function Base.union(p1::T,p2::S) where T <: AbstractParticles{F,NT} where S <: AbstractParticles{F,NS} where F where NT where NS
T.name.wrapper{F,NT+NS}([p1.particles; p2.particles])
end
``````

It does not feel like I’m supposed to use the `T.name.wrapper`

Edit 2:
I can also put the function definition in a loop over the different possible `T` and `@eval` the function into existence.

No, you cannot do this in general. This is why `similar` exists for arrays and you should probably use a similar approach. X-ref:

2 Likes

Out of curiosity, why don’t you want this? After all, `T` does include parameters `F` and `NT` according to your first attempt above.

The accepted definition looks fine to me so I am curious why you don’t like it.

I didn’t want the type parameters included as I would like to modify them, in my case call `T{F,NT+NS}`.

Thanks for the link, which led me to this section of the manual
https://docs.julialang.org/en/latest/manual/methods/#Building-a-similar-type-with-a-different-type-parameter-1
which is exactly what I would like to do