Adds type parameters to Intersection for more precision

This allows us to be completely precise about the kinds of intersections we have:

`Intersection[InclusiveLower, ExclusiveUpper, T]` being a common one, or `Interval.InLowExUp[T]`.

This is binary incompatible, but I think worth it. With this, I think we can remove the use of tuples as ranges, which is unclear about what is meant (same with single values as bounds where an Upper or Lower would do).