Make an existing type a child of an abstract type

Is it possible to make an existing type a child of an abstract type?
Something like this?

using StaticArrays
abstract type Abstract3DVector end
struct type SVector{3} <: Abstract3DVector end

Unfortunately it does not work:

julia> SVector{3} <: Abstract3DVector

No. But you can wrap it and type the wrapper.

Heres a toy example, AbstractVector3D should actualy be <: AbstractArray{T,N}:

abstract type Vector3D <: AbstracVector3D

Base.parent(a::Vector3D) =

Then you can write out all the SVector methods you need manually like:

getindex(a::Vector3D, I...) = getindex(parent(a), I...)

Or use the @forward macro in Lazy.jl to do them all at once. I can’t recall exactly what you need here.

But first you should have a good reason why you need such specialized types.


Maybe related (and also unsolved):

1 Like

This seems like a situation where a trait might be more appropriate than an abstract type. Traits, unlike abstract types, are easy to add to any type, even after that type has been defined. For example:

julia> struct ExistingType

julia> is_cool(::Type{T}) where {T} = false
is_cool (generic function with 1 method)

julia> is_cool(::Type{ExistingType}) = true
is_cool (generic function with 2 methods)

julia> function check_coolness(x::T) where {T}
         if is_cool(T)
check_coolness (generic function with 1 method)

julia> check_coolness(ExistingType(1))

In this case, the is_cool is just a function that returns a boolean, and we can use that inside an if statement to check properties of the type. Note that Julia is pretty clever about propagating types and constants, so the actual if statement is optimized away in the resulting code:

julia> @code_warntype check_coolness(ExistingType(1))
1 ─ %1 = invoke Main.println("Cool!"::String)::Core.Compiler.Const(nothing, false)
└──      return %1 

If you want your trait to help control method dispatch, then you can use “Holy-traits” and define new types to represent the trait of interest:

julia> struct IsCool end
julia> struct NotCool end

julia> coolness(::Type{T}) where {T} = NotCool()
coolness (generic function with 1 method)

julia> coolness(::Type{ExistingType}) = IsCool()
coolness (generic function with 2 methods)

julia> check_coolness_trait(x::T) where {T} = check_coolness_trait(coolness(T), x)
check_coolness_trait (generic function with 1 method)

julia> check_coolness_trait(::IsCool, x) = println("$x is cool")
check_coolness_trait (generic function with 2 methods)

julia> check_coolness_trait(::NotCool, x) = println("$x is not cool")
check_coolness_trait (generic function with 3 methods)

And we can use it like so:

julia> check_coolness_trait(1)
1 is not cool

julia> check_coolness_trait(ExistingType(1))
ExistingType(1) is cool