On this page:
Range
Sequence  Range
List  Range
..
..
..=
..=
<..<
<..<
<..=
<..=
Range.from_  to
Range.from_  to
Range.from_  to_  inclusive
Range.from_  to_  inclusive
Range.from
Range.from
Range.from_  exclusive_  to
Range.from_  exclusive_  to
Range.from_  exclusive_  to_  inclusive
Range.from_  exclusive_  to_  inclusive
Range.from_  exclusive
Range.from_  exclusive
Range.to
Range.to
Range.to_  inclusive
Range.to_  inclusive
Range.full
Range.full
Range.start
Range.end
Range.includes_  start
Range.includes_  end
Range.has_  element
Range.encloses
Range.is_  connected
Range.overlaps
Range.span
Range.gap
Range.intersect
Range.to_  list
Range.to_  sequence
Range.step_  by
8.13.0.9

6.37 Ranges🔗ℹ

A range, or an interval, represents a contiguous set of integers between two points. When the starting point is included, the range can be used as a sequence; in addition, when the ending point is not #inf, the range is listable.

The . operator can be used on a range expression as equivalent to calling Range functions:

rge.start()

 is 

Range.start(rge)

rge.end()

 is 

Range.end(rge)

rge.includes_start()

 is 

Range.includes_start(rge)

rge.includes_end()

 is 

Range.includes_end(rge)

rge.has_element(int)

 is 

Range.has_element(rge, int)

rge.encloses(rge2, ...)

 is 

Range.encloses(rge, rge2, ...)

rge.is_connected(rge2)

 is 

Range.is_connected(rge, rge2)

rge.overlaps(rge2)

 is 

Range.overlaps(rge, rge2)

rge.span(rge2, ...)

 is 

Range.span(rge, rge2, ...)

rge.gap(rge2)

 is 

Range.gap(rge, rge2)

rge.intersect(rge2, ...)

 is 

Range.intersect(rge, rge2, ...)

The . operator can be used on a range (sequenceable) expression as equivalent to calling Range functions:

rge.to_sequence()

 is 

Range.to_sequence(rge)

rge.step_by(step)

 is 

Range.step_by(rge, step)

The . operator can be used on a range (listable) expression as equivalent to calling Range functions:

rge.to_list()

 is 

Range.to_list(rge)

annotation

Range

 

annotation

SequenceRange

 

annotation

ListRange

The Range annotaiton matches any range.

The SequenceRange annotation matches a range that can be used as a sequence, for which Range.includes_start returns true.

The ListRange annotation matches a range that is listable, for which Range.includes_start returns true, and Range.end returns non-#inf.

Static information associated by SequenceRange or ListRange makes an expression acceptable as a sequence to for in static mode.

expression

start_expr .. end_expr

 

binding operator

start_bind .. end_bind

 

expression

start_expr ..

 

binding operator

start_bind ..

 

expression

.. end_expr

 

binding operator

.. end_bind

 

expression

..

 

binding operator

..

The same as Range.from_to, Range.from, Range.to, and Range.full, respectively.

When start_expr .. end_expr or start_expr .. is used in an each clause of for, the optimization is more aggressive in that no intermediate range is created.

expression

start_expr ..= end_expr

 

binding operator

start_bind ..= end_bind

 

expression

..= end_expr

 

binding operator

..= end_bind

The same as Range.from_to_inclusive and Range.to_inclusive, respectively.

When start_expr ..= end_expr is used in an each clause of for, the optimization is more aggressive in that no intermediate range is created.

expression

start_expr <..< end_expr

 

binding operator

start_bind <..< end_bind

 

expression

start_expr <..<

 

binding operator

start_bind <..<

The same as Range.from_exclusive_to and Range.from_exclusive, respectively.

expression

start_expr <..= end_expr

 

binding operator

start_bind <..= end_bind

function

fun Range.from_to(start :: Int, end :: Int) :: ListRange

 

binding operator

Range.from_to(start_bind, end_bind)

Constructs a range that includes start, but does not include end. The corresponding binding matches the constructed range.

function

fun Range.from_to_inclusive(start :: Int, end :: Int)

  :: ListRange

 

binding operator

Range.from_to_inclusive(start_bind, end_bind)

Constructs a range that includes both start and end. The corresponding binding matches the constructed range.

function

fun Range.from(start :: Int) :: SequenceRange

 

binding operator

Range.from(start_bind)

Constructs a range that includes start, and with #inf as the ending point. The corresponding binding matches the constructed range.

function

fun Range.from_exclusive_to(start :: Int, end :: Int)

  :: Range

 

binding operator

Range.from_exclusive_to(start_bind, end_bind)

Constructs a range that does not include either start or end. The corresponding binding matches the constructed range.

function

fun Range.from_exclusive_to_inclusive(start :: Int,

                                      end :: Int)

  :: Range

 

binding operator

Range.from_exclusive_to_inclusive(start_bind,

                                  end_bind)

Constructs a range that does not include start, but includes end. The corresponding binding matches the constructed range.

function

fun Range.from_exclusive(start :: Int) :: Range

 

binding operator

Range.from_exclusive(start_bind)

Constructs a range that does not include start, and with #inf as the ending point. The corresponding binding matches the constructed range.

function

fun Range.to(end :: Int) :: Range

 

binding operator

Range.to(end_bind)

Constructs a range with #neginf as the starting point, and does not include end. The corresponding binding matches the constructed range.

function

fun Range.to_inclusive(end :: Int) :: Range

 

binding operator

Range.to_inclusive(end_bind)

Constructs a range with #neginf as the starting point, and includes end. The corresponding binding matches the constructed range.

function

fun Range.full() :: Range

 

binding operator

Range.full()

Constructs a range with #neginf as the starting point and #inf as the ending point. The corresponding binding matches the constructed range.

function

fun Range.start(rge :: Range) :: Int || matching(#neginf)

 

function

fun Range.end(rge :: Range) :: Int || matching(#inf)

Returns the starting point and ending point of rge, respectively. The starting point can be #neginf, and the ending point can be #inf, indicating the lack of a starting point or ending point.

Returns #true if rge includes the starting point and the ending point, respectively, #false otherwise. A #neginf starting point or #inf ending point cannot be included.

function

fun Range.has_element(rge :: Range, int :: Int) :: Boolean

Checks whether rge has int in the range that it represents.

> (3..=7).has_element(5)

#true

> (3..=7).has_element(7)

#true

> (3..=7).has_element(10)

#false

function

fun Range.encloses(rge :: Range, ...) :: Boolean

Checks whether rges are in enclosing order. A range rge encloses another range rge2 when rge has every integer in rge2. Every range encloses itself, and empty ranges never enclose non-empty ranges.

> Range.encloses()

#true

> (2 <..< 8).encloses()

#true

> (2 <..< 8).encloses(4..=6)

#true

> (2 <..< 8).encloses(2..=6, 4..=6)

#false

> (2 <..< 8).encloses(5..)

#false

> (2 <..<).encloses(5..)

#true

function

fun Range.is_connected(rge :: Range, rge2 :: Range) :: Boolean

Checks whether rge is connected with rge2, that is, whether there exists a range (possibly empty) that is enclosed by both rge and rge2.

> (2..=7).is_connected(3 <..< 8)

#true

> (2..=5).is_connected(5 <..< 8)

#true

> (2 <..< 5).is_connected(5 <..< 8)

#false

function

fun Range.overlaps(rge :: Range, rge2 :: Range) :: Boolean

Checks whether rge overlaps with rge2, that is, whether there exists a non-empty range that is enclosed by both rge and rge2.

> (2..=7).overlaps(3 <..< 8)

#true

> (2..=5).overlaps(5..=8)

#true

> (2..=5).overlaps(5 <..< 8)

#false

function

fun Range.span(rge0 :: Range, rge :: Range, ...) :: Range

Returns the smallest range that encloses all rges (including rge0).

> (2..=5).span()

2 ..= 5

> (2..=5).span(8 <..< 9)

2 .. 9

> (..4).span(6..=6)

..= 6

> (2 <..< 8).span(..=5, 8 <..< 9)

.. 9

function

fun Range.gap(rge :: Range, rge2 :: Range) :: maybe(Range)

Returns the largest range that lies between rge and rge2, or #false if no such range exists (precisely when rge overlaps with rge2).

> (2..=5).gap(8..=9)

5 <..< 8

> (..4).gap(6..=6)

4 .. 6

> (2 <..< 8).gap(8..=10)

8 .. 8

> (2..=8).gap(8..=10)

#false

function

fun Range.intersect(rge :: Range, ...) :: maybe(Range)

Returns the intersection of all rges, or #false if no such range exists. The intersection of a range rge and another range rge2 is the largest range that is enclosed by both rge and rge2, which only exists when rge is connected with rge2.

> Range.intersect()

..

> (2..=8).intersect()

2 ..= 8

> (2..=8).intersect(4 <..< 16)

4 <..= 8

> (4 <..<).intersect(..6, 2..=8)

4 <..< 6

> (2 <..< 8).intersect(..=5)

2 <..= 5

> (2 <..< 8).intersect(8 <..< 10)

#false

function

fun Range.to_list(rge :: ListRange) :: List

Implements Listable by returning a list of integers in rge in order.

Implements Sequenceable by returning a sequence of integers in rge in order. The sequence is infinite when the ending point is #inf.

function

fun Range.step_by(rge :: SequenceRange, step :: PosInt)

  :: Sequence

Returns a sequence of integers in rge in order, stepping by the given step size.

When invoked as rge.step_by(step) in an each clause of for, the sequence is optimized, in addition to the optimization in .. or ..=.