```"Abstraction of [[ordinal types|Ordinal]] whose values may
be used as endpoints of a [[span]] or [[measure]].

An `Enumerable` type is characterized by each element
having well-defined [[offset]] and [[neighbour]] functions.
Given an instance `x` of an enumerable type `X`:

- for any integer-valued offset, there is a unique
_neighbour_ `y` of `X` with that offset, and
- if `y` is an instance of `X`, then there is a
well-defined integer-valued _offset_ of `x` from `y`.

The offset function must satisfy:

- `x.offset(x) == 0`, and
- `x.successor.offset(x) == 1` if `x!=x.successor`.

The neighbour function must satisfy:

- `x.neighbour(0) == x`,
- `x.neighbour(n-1) == x.neighbour(n).predecessor`, and
- `x.neighbour(n+1) == x.neighbour(n).successor`.

Of course, it follows that:

- `x.neighbour(-1) == x.predecessor`, and
- `x.neighbour(1) == x.successor`.

An enumerable type may be _linear_ or _recursive_. If `X`
is a linear enumerable type, then the offset function
satisfies:

- `x.predecessor.offset(x) == -1` if `x!=x.predecessor`,
- `x.offset(y) == -y.offset(x)` for any instance `y` of `X`,
and
- `x.offset(y) == x.offset(z) + z.offset(y)`.

Otherwise, `X` is a recursive enumerable type with a finite
list of enumerated instances of size `count`, and its
offset and neighbour functions must satisfy:

- `x.neighbour(count)==x`,
- `x.offset(y) >= 0` for any instance `y` of `X`, and
- `x.predecessor.offset(x) == count - 1`.

A range of values of an enumerable type may be specified
using:

- the _span operator_, written `first..last`, or
- the _segment operator_, written `first:length`."
see (`class Range`,
`function span`, `function measure`)
shared interface Enumerable<Other> of Other
satisfies Ordinal<Other>
given Other satisfies Enumerable<Other> {

"The indirect successor or predecessor at the given
[[offset]], where:

- `x.neighbour(0) == x`,
- `x.neighbour(i+1) == x.neighbour(i).successor`, and
- `x.neighbour(i-1) == x.neighbour(i).predecessor`."
throws (`class OverflowException`,
"if the neighbour cannot be represented as an
instance of the type")
since("1.1.0")
shared formal Other neighbour(Integer offset);

shared actual default Other successor => neighbour(1);
shared actual default Other predecessor => neighbour(-1);

"Compute the offset from the given value, where:

- `x.offset(x) == 0`, and
- `x.successor.offset(x) == 1` if `x!=x.successor`."
throws (`class OverflowException`,
"if the offset cannot be represented as an
integer")
since("1.1.0")
shared formal Integer offset(Other other);

"The sign of the offset from the given value."
since("1.1.0")
shared default Integer offsetSign(Other other)
=> offset(other).sign;

}
```