This is a bit tricky I feel, but I didn’t really found out how to separate the two cases.
I have an abstract type AbstractAgent. I have a model type which is parameterized on subtypes of my abstract type, see the following MWE:
abstract type AbstractAgent end
struct ABM{A<:AbstractAgent}
end
struct A <: AbstractAgent
end
model1 = ABM{A}()
struct B <: AbstractAgent
end
struct C <: AbstractAgent
end
model2 = ABM{Union{A, B, C}}()
I have a function which I want to make a dispatch on whether the type A contained in ABM is concrete or a Union (I am really targeting unions of concrete types, if that is even possible).
However they both print generic, pressumably becase t A as well as Union{A, B, C} are subtypes of AbstractAgent. How can I achieve the dispatch rule I want…?
Nope, this doesn’t change anything, even if I do not define the method step!(model::ABM) = println("generic") at all, and use your suggestion, both calls still yield generic.
Indeed. Not a solution, but maybe a reflection. Given the similar relationship
Union{Int32, Int64} <: Integer = true
One variable instance can be either one type or the other, so it doesn’t make sense to define a method that is specific for Union types. Except that the variable is a container with more than one value, in which case the dispatch should be on the type of the container.
What you can do is the contrary of being generic:
julia> not_generic_step!(model) = println("not generic")
not_generic_step! (generic function with 1 method)
julia> step!(model::ABM{A}) = not_generic_step!(model)
step! (generic function with 4 methods)
julia> step!(model::ABM{B}) = not_generic_step!(model)
step! (generic function with 5 methods)
julia> step!(model) = println("generic")
step! (generic function with 3 methods)
julia> step!(model1)
not generic
julia> step!(model2)
generic