A range of values: a lower bound, an upper bound, and whether each is inclusive.
Ash.Type.Range casts to and from it. In bounds, [ or ] is inclusive and ( or
) exclusive. The default, :"[)", is inclusive-exclusive. A nil bound is unbounded.
A range holding no values is empty: see empty/0.
PostgreSQL
Ash.Range follows PostgreSQL's ranges: the same bounds, every empty range cast to
one, every range holding the empty range, and the same sort order (compare/2).
| the question | PostgreSQL | Ash.Range |
|---|---|---|
| do they share a value? | &&, "overlaps" | intersects?/2 |
| does one hold a value, or the other range? | @>, "contains" | contains?/2 |
| does one meet the other, either way round? | -|- | adjacent?/2 |
| which of Allen's relations holds? | — | relation/2 |
PostgreSQL's overlaps and contains are wider than Allen's: [1, 10) intersects and
contains [3, 5), and their relation is :contains.
Summary
Functions
Whether one range meets the other, in either order: [1, 5) and [5, 9) are adjacent,
[1, 5] and [5, 9) share 5, and [1, 5) and (5, 9) leave it out. An empty range is
adjacent to nothing.
Compares two ranges: empty first, then by lower bound, then by upper bound. Unbounded below sorts first, and unbounded above last. Of two bounds on the
same value, [1 sorts before (1, and 5) before 5].
Whether the range holds value, which may be a value or another range.
The empty range, holding no values. A range such as [1, 1) holds none, and
Ash.Type.Range casts it to this.
Whether the range holds no values: empty/0, or bounds holding nothing, such as
[3, 1) or [1, 1). A range unbounded at either end is never empty.
Whether two ranges share a value: [1, 3) and [3, 5) do not, [1, 3] and [3, 5) do.
An empty range intersects nothing.
Whether bounds makes the lower bound inclusive.
Which of Allen's thirteen relations left has to right, or nil if either is empty.
Exactly one holds for two non-empty ranges.
The thirteen relations relation/2 returns, in Allen's order: from left furthest
before right to furthest after. Their positions can index a thirteen-bit mask.
Whether bounds makes the upper bound inclusive.
Whether bounds is one of :"[)", :"[]", :"()" or :"(]".
Types
@type allen() ::
:precedes
| :meets
| :overlaps
| :finished_by
| :contains
| :starts
| :equals
| :started_by
| :during
| :finishes
| :overlapped_by
| :met_by
| :preceded_by
One of Allen's thirteen interval relations.
@type bounds() :: :"[)" | :"[]" | :"()" | :"(]"
Functions
Whether one range meets the other, in either order: [1, 5) and [5, 9) are adjacent,
[1, 5] and [5, 9) share 5, and [1, 5) and (5, 9) leave it out. An empty range is
adjacent to nothing.
Consecutive ranges, each meeting the next, hold every value from the first lower bound to the last upper bound once.
Compare ranges cast by Ash.Type.Range: as integers, [1, 4] and [5, 9) are adjacent,
since [1, 4] is cast to [1, 5).
Compares two ranges: empty first, then by lower bound, then by upper bound. Unbounded below sorts first, and unbounded above last. Of two bounds on the
same value, [1 sorts before (1, and 5) before 5].
A sort order: [1, 10) sorts before [3, 5) though it holds it.
Whether the range holds value, which may be a value or another range.
A range holds another range lying within it, and every range holds the empty range.
@spec empty() :: t()
The empty range, holding no values. A range such as [1, 1) holds none, and
Ash.Type.Range casts it to this.
iex> Ash.Range.empty()
%Ash.Range{lower: nil, upper: nil, bounds: :"[)", empty?: true}
Whether the range holds no values: empty/0, or bounds holding nothing, such as
[3, 1) or [1, 1). A range unbounded at either end is never empty.
Whether two ranges share a value: [1, 3) and [3, 5) do not, [1, 3] and [3, 5) do.
An empty range intersects nothing.
Allen's :overlaps is narrower: [1, 10) intersects [3, 5), and relation/2 gives
:contains.
Whether bounds makes the lower bound inclusive.
Which of Allen's thirteen relations left has to right, or nil if either is empty.
Exactly one holds for two non-empty ranges.
[1, 5) meets [5, 9): one ends where the other begins, and exactly one includes that
value. [1, 5] overlaps [5, 9), and [1, 5) precedes (5, 9).
iex> Ash.Range.relation(%Ash.Range{lower: 1, upper: 5}, %Ash.Range{lower: 5, upper: 9})
:meets
@spec relations() :: [allen()]
The thirteen relations relation/2 returns, in Allen's order: from left furthest
before right to furthest after. Their positions can index a thirteen-bit mask.
iex> Ash.Range.relations()
[:precedes, :meets, :overlaps, :finished_by, :contains, :starts, :equals, :started_by,
:during, :finishes, :overlapped_by, :met_by, :preceded_by]
Whether bounds makes the upper bound inclusive.
Whether bounds is one of :"[)", :"[]", :"()" or :"(]".