Abstract constructor

I have a set of types that are related, e.g. by composition, but also logically (eg one can be converted to another).

I have a parallel set of types that satisfy the same relations.

I’d like to put as much as possible in an abstract interface. Here is an example:

abstract type AbstractT1 end
abstract type AbstractT2 end

struct A1 <: AbstractT1
    x::Int
end

struct A2 <: AbstractT2
    a1::A1
end

struct B1 <: AbstractT1
    x::Int
end

struct B2 <: AbstractT2
    b1::B1
end

outer_type(::Type{A1}) = A2
outer_type(::Type{B1}) = B2

function double_T2(t1::T) where {T <: AbstractT1}
   return outer_type(T)(T(2 * t1.x))
end
julia> double_T2(A1(2))
A2(A1(4))

julia> double_T2(B1(3))
B2(B1(6))

In my actual use case, there are more types with more complex realtionships in each set. There are also more than two sets. I am currently using more functions like outer_type.

Something tells me that I am missing a more elegant way to do this. Has anyone run into this before ?

I guess you could encode the information provided by outer_type & friends in type parameters, eg

struct B1 <: AbstractT2{B2}

but I actually find methods more flexible so I would do it like you do above, even at the expense of a bit more code. If that becomes too repetitive, consider a macro.

1 Like