Additional accessor and convert functions - #108
Conversation
Codecov Report
@@ Coverage Diff @@
## master #108 +/- ##
==========================================
- Coverage 73.50% 73.44% -0.06%
==========================================
Files 8 8
Lines 400 403 +3
==========================================
+ Hits 294 296 +2
- Misses 106 107 +1
Continue to review full report at Codecov.
|
omus
left a comment
There was a problem hiding this comment.
The new convert method looks good to me. I'm in favour of that change and I think it's best if the containsfirst/containslast change was put into a separate PR so that the convert can proceed.
| end | ||
|
|
||
| function Base.convert(::Type{Interval{T,L,R}}, interval::Interval{N,L,R}) where {T,N,L,R} | ||
| return Interval{L,R}(convert(T, first(interval)), convert(T, last(interval))) |
There was a problem hiding this comment.
| return Interval{L,R}(convert(T, first(interval)), convert(T, last(interval))) | |
| return Interval{T,L,R}(first(interval), last(interval)) |
| isclosed(interval::AbstractInterval{T,L,R}) where {T,L,R} = L === Closed && R === Closed | ||
| Base.isopen(interval::AbstractInterval{T,L,R}) where {T,L,R} = L === Open && R === Open | ||
| containsfirst(interval::AbstractInterval{T,L,R}) where {T,L,R} = L === Closed | ||
| containslast(interval::AbstractInterval{T,L,R}) where {T,L,R} = R === Closed |
There was a problem hiding this comment.
I think this functionality is useful but the name needs more consideration. There may be a rename of first/last in the near future: #90
|
I've made the change and added an additional promote_rule function for promoting intervals. |
| end | ||
| end | ||
|
|
||
| function Base.convert(::Type{<:Interval{T}}, interval::Interval{S,L,R}) where {T,S,L,R} |
There was a problem hiding this comment.
| function Base.convert(::Type{<:Interval{T}}, interval::Interval{S,L,R}) where {T,S,L,R} | |
| function Base.convert(::Type{Interval{T}}, interval::Interval{S,L,R}) where {T,S,L,R} |
| @test_throws DomainError convert(Int, Interval{Closed, Open}(10, 10)) | ||
| @test convert(Int, Interval{Closed, Closed}(10, 10)) == 10 | ||
| @test_throws DomainError convert(Int, Interval{Closed, Closed}(10, 11)) | ||
| @test convert(Interval{Float64, Closed, Closed}, Interval(1,2)) == Interval{Float64, Closed, Closed}(1.0,2.0) |
There was a problem hiding this comment.
Hmmm, convert(Interval{Float64, Open, Open}, Interval(1,2)) isn't lossless conversion. This means that the convert method should probably be defined as: Base.convert(::Type{Interval{T}}, interval::Interval{S,L,R}) where {T,S,L,R}
There was a problem hiding this comment.
Would it also be useful to include Base.convert(::Type{Interval{T,L,R}}, interval::Interval{S}) where {T,S,L,R} such that if you need to convert from Closed Closed to e.g. Open Open you can? Should this type of conversion include Closed -> Open but not Open -> Closed
There was a problem hiding this comment.
I think this would make more sense as a constructor: https://docs.julialang.org/en/v1/manual/conversion-and-promotion/#Conversion-vs.-Construction-1.
I'd probably leave this out unless you have a use case.
| interval1 = Interval{L1, R1}(a1, b1) | ||
| interval2 = Interval{L2, R2}(a2, b2) | ||
| @test promote(interval1, interval2) == (Interval{L1,R1}(promote(a1, b1)...), Interval{L2,R2}(promote(a2, b2)...)) |
There was a problem hiding this comment.
| interval1 = Interval{L1, R1}(a1, b1) | |
| interval2 = Interval{L2, R2}(a2, b2) | |
| @test promote(interval1, interval2) == (Interval{L1,R1}(promote(a1, b1)...), Interval{L2,R2}(promote(a2, b2)...)) | |
| interval1 = Interval{L1, R1}(a1, b1) | |
| interval2 = Interval{L2, R2}(a2, b2) | |
| promoted1 = Interval{L1,R1}(promote(a1, b1)...) | |
| promoted2 = Interval{L2,R2}(promote(a2, b2)...) | |
| @test promote(interval1, interval2) == (promoted1, promoted2) |
| Base.promote_rule(::Type{Interval{T,L1,R1}}, ::Type{Interval{S,L2,R2}}) where {T,S,L1,R1,L2,R2} = Interval{promote_type(T,S), <:Union{L1,L2}, <:Union{R1,R2}} | ||
| # hacky way to fix situations where T and S are the same but L and R are different | ||
| Base.not_sametype(x::Tuple{Interval{T,L1,R1}, Interval{T,L2,R2}}, y::Tuple{Interval{T,L1,R1}, Interval{T,L2,R2}}) where {T,L1,R1,L2,R2} = nothing |
There was a problem hiding this comment.
Probably we should just define:
Base.promote_rule(::Type{Interval{T,L,R}}, ::Type{Interval{S,L,R}}) where {T,S,L,R} = Interval{promote_type(T,S), L, R}I suspect this would eliminate the need for the hack
Added some functions simple
containsfirst()andconstainslast()functions and a convert function to allow Intervals to be added to Interval arrays with different types e.g.