ListPair structure
May 20, 2026 ยท View on GitHub
The ListPair structure provides operations for working with two lists
simultaneously. Operations whose names do not end in Eq silently
ignore excess elements of the longer list; those ending in Eq raise
UnequalLengths when the lists differ in length.
Specified by the Standard ML Basis Library.
Synopsis
exception UnequalLengths val zip : 'a list * 'b list -> ('a * 'b) list val unzip : ('a * 'b) list -> 'a list * 'b list val map : ('a * 'b -> 'c) -> 'a list * 'b list -> 'c list val app : ('a * 'b -> unit) -> 'a list * 'b list -> unit val all : ('a * 'b -> bool) -> 'a list * 'b list -> bool val exists : ('a * 'b -> bool) -> 'a list * 'b list -> bool val foldr : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c val foldl : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c val allEq : ('a * 'b -> bool) -> 'a list * 'b list -> bool val zipEq : 'a list * 'b list -> ('a * 'b) list val mapEq : ('a * 'b -> 'c) -> 'a list * 'b list -> 'c list val appEq : ('a * 'b -> unit) -> 'a list * 'b list -> unit val foldrEq : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c val foldlEq : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c
exception UnequalLengths
is raised by those functions that require arguments of identical length.
zip
zip (l1, l2) combines the two lists l1 and l2 into a list of
pairs, with the first element of each list comprising the first
element of the result, the second elements comprising the second
element of the result, and so on. If the lists are of unequal
lengths, zip ignores the excess elements from the tail of the longer
one.
unzip
unzip l returns a pair of lists formed by splitting the elements of
l. This is the inverse of zip for equal length lists.
map
map f (l1, l2) maps the function f over the list of pairs of
elements generated from left to right from the lists l1 and l2,
returning the list of results. If the lists are of unequal lengths,
ignores the excess elements from the tail of the longer one. It is
equivalent to:
List.map f (zip (l1, l2))
ignoring possible side effects of the function f.
app
app f (l1, l2) applies the function f to the list of pairs of
elements generated from left to right from the lists l1 and l2. If
the lists are of unequal lengths, ignores the excess elements from the
tail of the longer one. It is equivalent to:
List.app f (zip (l1, l2))
ignoring possible side effects of the function f.
all
all f (l1, l2) provides short-circuit testing of a predicate over a pair of lists.
It is equivalent to:
List.all f (zip (l1, l2))
exists
exists f (l1, l2) provides short-circuit testing of a predicate over a pair of lists.
It is equivalent to:
List.exists f (zip (l1, l2))
foldr
foldr f init (l1, l2) returns the result of folding the function f
in the specified direction over the pair of lists l1 and l2
starting with the value init. It is equivalent to:
List.foldr f' init (zip (l1, l2))
where f' is fn ((a,b),c) => f(a,b,c) and ignoring possible
side effects of the function f.
foldl
foldl f init (l1, l2) returns the result of folding the function f
in the specified direction over the pair of lists l1 and l2
starting with the value init. It is equivalent to:
List.foldl f' init (zip (l1, l2))
where f' is fn ((a,b),c) => f(a,b,c) and ignoring possible
side effects of the function f.
allEq
allEq f (l1, l2) returns true if l1 and l2 have equal length
and all pairs of elements satisfy the predicate f. That is, the
expression is equivalent to:
(List.length l1 = List.length l2) andalso (List.all f (zip (l1, l2)))
This function does not appear to have any nice algebraic relation with the other functions, but it is included as providing a useful notion of equality, analogous to the notion of equality of lists over equality types.
Implementation note:
The implementation is simple:
fun allEq p ([], []) = true | allEq p (x::xs, y::ys) = p(x,y) andalso allEq p (xs,ys) | allEq _ _ = false
zipEq
zipEq (l1, l2) combines the two lists l1 and l2 into a list of
pairs, with the first element of each list comprising the first
element of the result, the second elements comprising the second
element of the result, and so on. If the lists are of unequal
lengths, zipEq raises the exception UnequalLengths.
mapEq
mapEq f (l1, l2) maps the function f over the list of pairs of
elements generated from left to right from the lists l1 and l2,
returning the list of results. If the lists are of unequal lengths,
raises UnequalLengths. It is equivalent to:
List.map f (zipEq (l1, l2))
ignoring possible side effects of the function f.
appEq
appEq f (l1, l2) applies the function f to the list of pairs of
elements generated from left to right from the lists l1 and l2. If
the lists are of unequal lengths, raises UnequalLengths. It is
equivalent to:
List.app f (zipEq (l1, l2))
ignoring possible side effects of the function f.
foldrEq
foldrEq f init (l1, l2) returns the result of folding the function
f in the specified direction over the pair of lists l1 and l2
starting with the value init. It is equivalent to:
List.foldr f' init (zipEq (l1, l2))
where f' is fn ((a,b),c) => f(a,b,c) and ignoring possible
side effects of the function f.
foldlEq
foldlEq f init (l1, l2) returns the result of folding the function
f in the specified direction over the pair of lists l1 and l2
starting with the value init. It is equivalent to:
List.foldl f' init (zipEq (l1, l2))
where f' is fn ((a,b),c) => f(a,b,c) and ignoring possible
side effects of the function f.