Created
August 31, 2024 11:23
-
-
Save apieum/0f59bde726e47b3b16d511c348abbc61 to your computer and use it in GitHub Desktop.
Traits in Julia
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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