6.31 Pairs and Pair Lists
A pair combines two values: a “first” value and a “rest” value. A pair list is a listable value that is constructed with pairs and the empty pair list; every non-empty pair list is a pair, a pair is a pair list only if its “rest” is a list.
pr.first
is
Pair.first(pr)
pr.rest
is
Pair.rest(pr)
lst.length()
is
PairList.length(lst)
lst.get(n)
is
PairList.get(lst, n)
lst.first
is
PairList.first(lst)
lst.last
is
PairList.last(lst)
lst.rest
is
PairList.rest(lst)
lst.reverse()
is
PairList.reverse(lst)
is
PairList.append(lst, lst2, ...)
lst.take(n)
is
PairList.take(lst, n)
lst.take_last(n)
is
PairList.take_last(lst, n)
lst.drop(n)
is
PairList.drop(lst, n)
lst.drop_last(n)
is
PairList.drop_last(lst, n)
is
PairList.has_element(lst, v, eqls, ...)
lst.find(pred)
is
PairList.find(lst, pred)
lst.remove(v)
is
PairList.remove(lst, v)
lst.map(func)
is
PairList.map(lst, func)
lst.for_each(func)
is
PairList.for_each(lst, func)
is
PairList.sort(lst, arg, ...)
lst.to_list()
is
PairList.to_list(lst)
lst.to_sequence()
is
PairList.to_sequence(lst)
> pr
Pair(1, 2)
> pr.first
1
> pr.rest
2
> y
2
def: value does not satisfy annotation
value: Pair(1, 2)
annotation: matching(Pair((_ :: String), (_ :: String)))
> y
2
Note that the difference between Pair.cons and
PairList.cons is that PairList.cons requires a list as is
second argument, which means that it always forms a list. In
contrast, Pair.cons allows any value as its second
argument—
> Pair.cons(1, 2)
Pair(1, 2)
> Pair.cons(1, [2, 3])
Pair(1, [2, 3])
> Pair.first(Pair("a", "b"))
"a"
"b"
annotation |
|
annotation |
Static information associated by PairList or PairList.of makes an expression acceptable as a sequence to for in static mode.
function | |||||||||
| |||||||||
expression | |||||||||
PairList[expr_or_splice, ...] | |||||||||
| |||||||||
repetition | |||||||||
PairList[repet_or_splice, ...] | |||||||||
| |||||||||
| |||||||||
| |||||||||
| |||||||||
| |||||||||
|
The #%brackets form is implicitly used when […] is used in in an expression position. See also Implicit Forms.
> lst
PairList[1, 2, 3]
> lst[0]
1
PairList[1, 2, 3, 4, 5]
> PairList[1, 2, 3]
PairList[1, 2, 3]
binding operator | ||||||
| ||||||
binding operator | ||||||
| ||||||
binding operator | ||||||
| ||||||
binding operator | ||||||
| ||||||
| ||||||
| ||||||
|
When & pair_list_bind is used, the rest of the list must match the pair_list_bind. Static information associated by PairList is propagated to pair_list_bind.
When repet_bind is used and does not impose a predicate or conversion on a matching value (e.g., repet_bind is an identifier), then the corresponding elements of a matching value are not traversed, which means that matching can be constant-time. Using this repetition for the tail a new list similarly avoids traversing the elements.
The #%brackets form is implicitly used when […] is used in in a binding position. See also Implicit Forms.
> y
3
> also_y
3
> xs
PairList[2, 3]
> PairList[x, ...]
PairList[2, 3]
annotation |
|
annotation |
> PairList[1] :: NonemptyPairList
PairList[1]
::: value does not satisfy annotation
value: PairList[]
annotation: NonemptyPairList
reducer |
> PairList.cons(1, PairList[2, 3])
PairList[1, 2, 3]
binding operator |
> x
1
> y
PairList[2, 3]
value |
|
binding operator |
"b"
> PairList["a", "b", "c"][1]
"b"
function |
fun PairList.first(lst :: NonemptyPairList) :: Any |
> PairList.first(PairList["a", "b", "c"])
"a"
"a"
function |
fun PairList.last(lst :: NonemptyPairList) :: Any |
> PairList.last(PairList["a", "b", "c"])
"c"
"c"
function |
> PairList.rest(PairList["a", "b", "c"])
PairList["b", "c"]
PairList["b", "c"]
repetition |
PairList.repet(list_expr) |
> block:
PairList[2, 3, 4]
> [PairList.repet(lst) + 1, ...]
[2, 3, 4]
> PairList.length(PairList[1, 4, 8])
3
> PairList.length(PairList[])
0
3
0
> PairList.reverse(PairList[1, 4, 8])
PairList[8, 4, 1]
PairList[8, 4, 1]
> PairList.append(PairList[1, 2, 3], PairList[4, 5], PairList[6])
PairList[1, 2, 3, 4, 5, 6]
PairList[1, 2, 3, 4, 5, 6]
function |
fun PairList.take(lst :: PairList, n :: NonnegInt) :: PairList |
|
function |
fun PairList.take_last(lst :: PairList, n :: NonnegInt) :: PairList |
PairList[1, 2]
PairList[4, 5]
PairList.take: list is shorter than the number of elements to take
list length: 1
number to take: 2
function |
fun PairList.drop(lst :: PairList, n :: NonnegInt) :: PairList |
|
function |
fun PairList.drop_last(lst :: PairList, n :: NonnegInt) :: PairList |
PairList[3, 4, 5]
PairList[1, 2, 3]
PairList.drop: list is shorter than the number of elements to drop
list length: 1
number to drop: 2
function | |||
|
#true
#false
function |
fun PairList.find(lst :: PairList, pred :: Function.of_arity(1)) :: Any |
2
#false
> [1, 2, 3, 2].remove(2)
[1, 3, 2]
function | ||
| ||
| ||
function | ||
|
> PairList.map(PairList[1, 2, 3], fun (x): x + 1)
PairList[2, 3, 4]
PairList[2, 3, 4]
1
2
3
function | |||
|
> PairList.sort(PairList[1, 3, 2])
PairList[1, 2, 3]
> PairList.sort(PairList[1, 3, 2], math.greater)
PairList[3, 2, 1]
function |
> PairList.iota(3)
PairList[0, 1, 2]
> PairList.iota(0)
PairList[]