Skip to content

Instantly share code, notes, and snippets.

@apieum
Created August 31, 2024 11:23
Show Gist options
  • Select an option

  • Save apieum/0f59bde726e47b3b16d511c348abbc61 to your computer and use it in GitHub Desktop.

Select an option

Save apieum/0f59bde726e47b3b16d511c348abbc61 to your computer and use it in GitHub Desktop.
Traits in Julia
using Test
import Base.getindex
abstract type A end
struct S{T<:A} end
function register! end
let subtypes = Dict()
typesof(::Type{S{T}}) where T = unbox(T)
typesof(a::Type{<:A}) = [a]
unbox(t) = Base.uniontypes(t)
function Base.getindex(s::Type{S}, i...)
t = Vector()
for j in i
push!(t, typesof(j)...)
end
u = Vector()
for k in t
if !haskey(subtypes, k)
subtypes[k] = [S{k}]
end
push!(u, Base.unique(subtypes[k])...)
end
return Union{u...}
end
global function register!(l::Type{<:S})
t = typesof(l)
for k in t
if !haskey(subtypes, k)
subtypes[k] = [S{k}]
end
push!(subtypes[k], l)
Base.unique!(subtypes[k])
end
end
end
struct A1 <: A
a::Int
A1() = new(1)
end
struct A2 <: A
a::Int
b::Int
A2() = new(1, 2)
end
struct A3 <: A
a::Int
b::Int
c::Int
A3() = new(1, 2, 3)
end
const L1=S{A1}
register!(L1)
const L2=S{A2}
register!(L2)
const L3=S{Union{A1, A2}}
register!(L3)
f1(a::L3) = @test a isa L3
f1(a)= @test a isa S[L3]
f1(L1())
f1(L2())
f1(L3())
f4(a::L1) = @test a isa L1
f4(a)= @test a isa S[L2]
f4(L1())
f4(L2())
f4(L3())
@test L3() isa S[L1]
@test L3() isa S[L2]
f2(a::S[L3]) = @test a isa S[L3]
f2(a)= @test false
f2(L1())
f2(L2())
f2(L3())
f3(a::S[L1]) = @test a isa S[L1]
f3(a) = @test a isa L2
f3(L1())
f3(L2())
f3(L3())
@test L1 <: S{A1}
@test L2 <: S{A2}
@test L3 <: S{Union{A2, A1}}
@test !(L3 <: L1)
@test !(L1 <: L3)
@test L1 <: S[L3]
@test !(L2 <: L3)
@test !(L3 <: L2)
@test L2 <: S[L3]
@test L3 <: S[L3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment