Operations on pairs of lists.
The ListPair structure provides operations on pairs of lists. The operations fall into two categories. Those in the first category, whose names do not end in "Eq", do not require that the lists have the same length. When the lists are of uneven lengths, the excess elements from the tail of the longer list are ignored. The operations in the second category, whose names have the suffix "Eq", differ from their similarly named operations in the first category only when the list arguments have unequal lengths, in which case they typically raise the UnequalLengths exception.structure ListPair : LIST_PAIR
signature LIST_PAIR = sig exception UnequalLengths val zip : 'a list * 'b list -> ('a * 'b) list val zipEq : 'a list * 'b list -> ('a * 'b) list val unzip : ('a * 'b) list -> 'a list * 'b list val app : ('a * 'b -> unit) -> 'a list * 'b list -> unit val appEq : ('a * 'b -> unit) -> 'a list * 'b list -> unit val map : ('a * 'b -> 'c) -> 'a list * 'b list -> 'c list val mapEq : ('a * 'b -> 'c) -> 'a list * 'b list -> 'c list val foldl : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c val foldr : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c val foldlEq : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c val foldrEq : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c val all : ('a * 'b -> bool) -> 'a list * 'b list -> bool val exists : ('a * 'b -> bool) -> 'a list * 'b list -> bool val allEq : ('a * 'b -> bool) -> 'a list * 'b list -> bool end
List.app f (zip (l1, l2)) List.app f (zipEq (l1, l2))ignoring possible side-effects of the function f.
List.map f (zip (l1, l2)) List.map f (zipEq (l1, l2))ignoring possible side-effects of the function f.
List.foldl f' init (zip (l1, l2)) List.foldr f' init (zip (l1, l2)) List.foldl f' init (zipEq (l1, l2)) 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.
List.all f (zip (l1, l2))
(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. The implementation is simple:
fun allEq p ([], []) = true | allEq p (x::xs, y::ys) = p(x,y) andalso allEq p (xs,ys) | allEq _ _ = false