-
Notifications
You must be signed in to change notification settings - Fork 27
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
Rethink unions and intersections #41
Comments
It's an interesting proposal. I guess the main alternative is like union(IntervalUnion.((1..2, 3.5..5))...) One potential advantage of this approach is that I'm not sure you need a separate |
Hi Folks. The solution I chose for |
I think the best behaviour is to mimic how For collections, it auto-promotes: A more general design might be able to include all of the following operations:
struct CombinationDomain{T, FF<:Function, DD<:Tuple} <: Domain{T}
op::FF
domains::DD
end
in(x, d::CombinationDomain) = d.op(in.(x, d.domains))
const UnionDomain{T,DD} = CombinationDomain{T,typeof(any),DD}
const IntersectDomain{T,DD} = CombinationDomain{T,typeof(all),DD}
setdiff_f(a,b) = a && !b
const SetDiffDomain{T,DD} where DD<:Tuple{A,B} where {A,B} = CombinationDomain{T,typeof(setdiff_f),DD} |
I guess it's a mix. The auto-promotion of numbers to arrays is necessitated because there isn't a way to express the union of two distinct numbers as a number. However, for a discrete set (aka, a collection), the output type tends to be preserved: we don't, for example, return a I can go either way here; I guess the advantage of your approach is that Either way, I will happily support you if you feel this is the right direction (and assuming, as I do, that @scheinerman, I also would not be opposed to |
Looking at Base's union code it should actually be possible to jack into the following line: union(s, sets...) = union!(emptymutable(s, promote_eltype(s, sets...)), s, sets...) I'm thinking something like this: eltype(x::AbstractInterval{T}) = Infinitesimal{T}
struct DomainStyle end
emptymutable(s, ::Infinitesimal) = DomainStyle()
union!(::DomainStyle, s...) = UnionDomain(s) ============= This has the obvious drawback that it is abusing abstract type UnionStyle end
struct SetStyle <: UnionStyle end
struct VectorStyle <: UnionStyle end
UnionStyle(::Type{<:AbstractSet}) = SetStyle()
UnionStyle(_) = VectorStyle()
struct Unioned{Style,SV}
args::SV
end
Unioned(args) = Unioned{combine_union_styles(args), typeof(args)}(args)
union(s...) = materialize(Unioned(s))
union!(x, s...) = materialize!(x, Unioned(s)) |
As I'm sure you see, that's problematic because The |
The following inconsistency feels "wrong":
Following the success of the lazy
Broadcasted
approach, I'd propose thatwhere
UnionDomain
(andIntersectDomain
) are lazy:as in https://github.com/JuliaApproximation/Domains.jl. This works as follows:
The current behaviour would be recovered via
The text was updated successfully, but these errors were encountered: