diff --git a/src/dual.jl b/src/dual.jl index aadc58e..e39c5c6 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -3,6 +3,11 @@ dual(x) = x nondual(r::AbstractUnitRange) = r isdual(::AbstractUnitRange) = false +dual_type(x) = dual_type(typeof(x)) +dual_type(T::Type) = T +nondual_type(x) = nondual_type(typeof(x)) +nondual_type(T::Type) = T + using LabelledNumbers: LabelledStyle, IsLabelled, NotLabelled, label, labelled, unlabel dual(i::LabelledInteger) = labelled(unlabel(i), dual(label(i))) diff --git a/src/gradedunitrange.jl b/src/gradedunitrange.jl index 37cda65..487552c 100644 --- a/src/gradedunitrange.jl +++ b/src/gradedunitrange.jl @@ -90,6 +90,10 @@ Base.eltype(::Type{<:GradedUnitRange{T}}) where {T} = T LabelledNumbers.label_type(g::AbstractGradedUnitRange) = label_type(typeof(g)) LabelledNumbers.label_type(T::Type{<:AbstractGradedUnitRange}) = label_type(eltype(T)) +sector_type(x) = sector_type(typeof(x)) +sector_type(T::Type) = error("Not implemented") +sector_type(T::Type{<:AbstractUnitRange}) = label_type(T) + function gradedrange(lblocklengths::AbstractVector{<:LabelledInteger}) brange = blockedrange(unlabel.(lblocklengths)) lblocklasts = labelled.(blocklasts(brange), label.(lblocklengths)) diff --git a/src/gradedunitrangedual.jl b/src/gradedunitrangedual.jl index 78cf48e..2d26d91 100644 --- a/src/gradedunitrangedual.jl +++ b/src/gradedunitrangedual.jl @@ -9,6 +9,21 @@ nondual(a::GradedUnitRangeDual) = a.nondual_unitrange dual(a::GradedUnitRangeDual) = nondual(a) flip(a::GradedUnitRangeDual) = dual(flip(nondual(a))) isdual(::GradedUnitRangeDual) = true + +function nondual_type( + ::Type{<:GradedUnitRangeDual{<:Any,<:Any,NondualUnitRange}} +) where {NondualUnitRange} + return NondualUnitRange +end +dual_type(T::Type{<:GradedUnitRangeDual}) = nondual_type(T) +function dual_type(type::Type{<:AbstractGradedUnitRange{T,BlockLasts}}) where {T,BlockLasts} + return GradedUnitRangeDual{T,BlockLasts,type} +end +function LabelledNumbers.label_type(type::Type{<:GradedUnitRangeDual}) + # `dual_type` right now doesn't do anything but anticipates defining `SectorDual`. + return dual_type(label_type(nondual_type(type))) +end + ## TODO: Define this to instantiate a dual unit range. ## materialize_dual(a::GradedUnitRangeDual) = materialize_dual(nondual(a)) diff --git a/src/labelledunitrangedual.jl b/src/labelledunitrangedual.jl index 319521e..b2ca841 100644 --- a/src/labelledunitrangedual.jl +++ b/src/labelledunitrangedual.jl @@ -14,9 +14,23 @@ label_dual(::IsLabelled, a::LabelledUnitRangeDual) = dual(label_dual(nondual(a)) isdual(::LabelledUnitRangeDual) = true blocklabels(la::LabelledUnitRangeDual) = [label(la)] +function nondual_type( + ::Type{<:LabelledUnitRangeDual{<:Any,NondualUnitRange}} +) where {NondualUnitRange} + return NondualUnitRange +end +dual_type(T::Type{<:LabelledUnitRangeDual}) = nondual_type(T) +function dual_type(T::Type{<:LabelledUnitRange}) + return LabelledUnitRangeDual{eltype(T),T} +end + LabelledNumbers.label(a::LabelledUnitRangeDual) = dual(label(nondual(a))) LabelledNumbers.unlabel(a::LabelledUnitRangeDual) = unlabel(nondual(a)) LabelledNumbers.LabelledStyle(::LabelledUnitRangeDual) = IsLabelled() +function LabelledNumbers.label_type(type::Type{<:LabelledUnitRangeDual}) + # `dual_type` right now doesn't do anything but anticipates defining `SectorDual`. + return dual_type(label_type(nondual_type(type))) +end for f in [:first, :getindex, :last, :length, :step] @eval Base.$f(a::LabelledUnitRangeDual, args...) = diff --git a/test/test_basics.jl b/test/test_basics.jl index 96e7dc6..cbd9bc4 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -13,7 +13,13 @@ using BlockArrays: combine_blockaxes, mortar using GradedUnitRanges: - GradedOneTo, GradedUnitRange, OneToOne, blocklabels, gradedrange, space_isequal + GradedOneTo, + GradedUnitRange, + OneToOne, + blocklabels, + gradedrange, + sector_type, + space_isequal using LabelledNumbers: LabelledUnitRange, islabelled, label, labelled, labelled_isequal, unlabel using Test: @test, @test_broken, @testset @@ -41,6 +47,7 @@ end gradedrange(["x" => 2, "y" => 3]), ) @test a isa GradedOneTo + @test sector_type(a) === String @test labelled_isequal(a, a) @test !labelled_isequal(a0, a) @test !labelled_isequal(a, a0) diff --git a/test/test_dual.jl b/test/test_dual.jl index 8c4370e..179e71e 100644 --- a/test/test_dual.jl +++ b/test/test_dual.jl @@ -14,8 +14,8 @@ using BlockArrays: mortar, combine_blockaxes using GradedUnitRanges: - GradedUnitRanges, AbstractGradedUnitRange, + GradedUnitRanges, GradedUnitRangeDual, LabelledUnitRangeDual, OneToOne, @@ -23,11 +23,14 @@ using GradedUnitRanges: blockmergesortperm, blocksortperm, dual, + dual_type, flip, - space_isequal, gradedrange, isdual, - nondual + nondual, + nondual_type, + space_isequal, + sector_type using LabelledNumbers: LabelledInteger, LabelledUnitRange, label, label_type, labelled, labelled_isequal, unlabel using Test: @test, @test_broken, @testset @@ -70,7 +73,8 @@ end @test !isdual(la) @test labelled_isequal(la, la) @test space_isequal(la, la) - @test label_type(la) == U1 + @test label_type(la) === U1 + @test sector_type(la) === U1 @test iterate(la) == (1, 1) @test iterate(la) == (1, 1) @@ -90,7 +94,13 @@ end @test isdual(lad) @test nondual(lad) === la @test dual(lad) === la - @test label_type(lad) == U1 + @test label_type(lad) === U1 + @test sector_type(lad) === U1 + + @test dual_type(la) === typeof(lad) + @test dual_type(lad) === typeof(la) + @test nondual_type(lad) === typeof(la) + @test nondual_type(la) === typeof(la) @test iterate(lad) == (1, 1) @test iterate(lad) == (1, 1) @@ -155,6 +165,7 @@ end @test eltype(ad) == LabelledInteger{Int,U1} @test blocklengths(ad) isa Vector @test eltype(blocklengths(ad)) == eltype(blocklengths(a)) + @test sector_type(a) === U1 @test space_isequal(dual(ad), a) @test space_isequal(nondual(ad), a) @@ -163,6 +174,11 @@ end @test !space_isequal(a, ad) @test !space_isequal(ad, a) + @test dual_type(a) === typeof(ad) + @test dual_type(ad) === typeof(a) + @test nondual_type(ad) === typeof(a) + @test nondual_type(a) === typeof(a) + @test isdual(ad) @test !isdual(a) @test axes(Base.Slice(a)) isa Tuple{typeof(a)}