TL; DR: for a given abstract type, generate a vector/tuple/whatever containing a default instance for each of its concrete subtypes.
un-XY: I have several concrete types that subtype an abstract supertype (possibly indirectly), and each of these concrete types defines two methods, for which I would like to check that they agree (let’s say in the “default” case). As such, I would like to
- iterate over all concrete types that subtype my abstract type
- register a
get_default()
function for each of these concrete types that gives me a default instance,def
, for the given concrete type - for
def
, run some routine to verify that the methods are consistent - as soon as an inconsistency is detected, error
To illustrate in a MWE (that won’t run because I don’t know how to define a few components…)
using Random
Random.seed!(42)
abstract type Abs_type end
abstract type Abs_sub1 <: Abs_type end
struct A <: Abs_type end
struct B <: Abs_sub_1 end
struct C <: Abs_sub_1 end
# Method 1 and method 2 should be such that method1(x, ::Abs_type) + method2(x, ::Abs_type) == 0
## Consistent definition for A
method1(x, ::A) = x
method2(x, ::A) = -x
## Consistent definition for B
method1(x, ::B) = -x
method2(x, ::B) = x
## Inconsistent definition for C
method1(x, ::C) = x
method2(x, ::C) = 0 * x
function test(N)
concrete_subtypes = get_concrete_subtypes(Abs_type) # How to get these?
x = rand(N)
for s in concrete_subtypes
s_def = get_default(s) # How to get these? I know I'll have to define get_default for each concrete subtype, but how do I dispatch on these?
@assert all(method1(xi, s) + method2(xi, s) ≈ 0 for xi in x)
end
return nothing
end