Skip to content

Rethink unions and intersections #41

Open
@dlfivefifty

Description

@dlfivefifty

The following inconsistency feels "wrong":

julia> union(1,2)
2-element Array{Int64,1}:
 1
 2

julia> union(1:1 , 2:2)
2-element Array{Int64,1}:
 1
 2

julia> union(1..1, 2..2)
ERROR: ArgumentError: Cannot construct union of disjoint sets.
Stacktrace:
 [1] _leq_union at /Users/solver/Projects/IntervalSets.jl/src/interval.jl:148 [inlined]
 [2] union(::Interval{:closed,:closed,Int64}, ::Interval{:closed,:closed,Int64}) at /Users/solver/Projects/IntervalSets.jl/src/interval.jl:125
 [3] top-level scope at none:0

Following the success of the lazy Broadcasted approach, I'd propose that

union(a::AbstractInterval, b::AbstractInterval) = UnionDomain(a,b)

where UnionDomain (and IntersectDomain) are lazy:

struct UnionDomain{T, D} <: Domain{T}
   domains::D
end
UnionDomain(a...) = UnionDomain{mapreduce(eltype,promote_type,a),typeof(a)}(a)
in(x, d::UnionDomain) = any(in.(x, d.domains))

as in https://github.com/JuliaApproximation/Domains.jl. This works as follows:

julia> UnionDomain(1..1, 2..2)
a union of 2 domains:
	1.	: 1..1
	2.	: 2..2

julia> 1  UnionDomain(1..1, 2..2)
true

julia> 2  UnionDomain(1..1, 2..2)
true

julia> 1.5  UnionDomain(1..1, 2..2)
false

The current behaviour would be recovered via

julia> Interval(union(1..2, 1.5..3))
1.0..3.0

julia> Interval(union(1..2, 1.5..3))
1.0..3.0

julia> Interval(union(1..1, 2..2))
ERROR: ArgumentError: Cannot construct interval from disjoint union of intervals.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions