Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional accessor and convert functions #108

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ function Base.convert(::Type{T}, interval::Interval{T}) where T
end
end

function Base.convert(::Type{<:Interval{T}}, interval::Interval{S,L,R}) where {T,S,L,R}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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}

return Interval{T,L,R}(first(interval), last(interval))
end

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
Comment on lines +196 to +198
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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


##### DISPLAY #####

function Base.show(io::IO, interval::Interval{T,L,R}) where {T,L,R}
Expand Down
15 changes: 15 additions & 0 deletions test/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ isinf(::TimeType) = false
@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)
Copy link
Collaborator

@omus omus Jul 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Collaborator

@omus omus Jul 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.


for T in (Date, DateTime)
dt = T(2013, 2, 13)
Expand All @@ -101,6 +102,20 @@ isinf(::TimeType) = false
@test eltype(Interval{Float64}(1,2)) == Float64
end

@testset "promotion" begin
for (a1, b1, _) in test_values
for (a2, b2, _) in test_values
for (L1, R1) in BOUND_PERMUTATIONS
for (L2, R2) in BOUND_PERMUTATIONS
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)...))
Comment on lines +110 to +112
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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)

end
end
end
end
end

@testset "accessors" begin
for (a, b, _) in test_values
for (L, R) in BOUND_PERMUTATIONS
Expand Down