From 404fede54a57ec088dad38899342663ae575af59 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 18 Apr 2017 10:45:28 +0200 Subject: [PATCH] Add a tail-recursive implementation of List.combine Closes #108. --- AUTHORS.adoc | 1 + src/core/CCList.ml | 20 ++++++++++++++++++++ src/core/CCList.mli | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/AUTHORS.adoc b/AUTHORS.adoc index fd3da2dc..755da15b 100644 --- a/AUTHORS.adoc +++ b/AUTHORS.adoc @@ -19,3 +19,4 @@ - Malcolm Matalka (`orbitz`) - David Sheets (@dsheets) - Glenn Slotte (glennsl) +- @LemonBoy diff --git a/src/core/CCList.ml b/src/core/CCList.ml index f4f3b9ea..9ac2f6b7 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -339,6 +339,26 @@ let partition_map f l = assert_equal [1;3] l2 *) +let combine l1 l2 = + let rec direct i l1 l2 = match l1, l2 with + | ([], []) -> [] + | _ when i=0 -> safe l1 l2 [] + | (x1::l1', x2::l2') -> (x1, x2) :: direct (i-1) l1' l2' + | (_, _) -> invalid_arg "CCList.combine" + and safe l1 l2 acc = match l1, l2 with + | ([], []) -> List.rev acc + | (x1::l1', x2::l2') -> safe l1' l2' @@ (x1, x2) :: acc + | (_, _) -> invalid_arg "CCList.combine" + in + direct direct_depth_default_ l1 l2 + +(*$T + try ignore (combine [1] []); false with Invalid_argument _ -> true + try ignore (combine (1--1001) (1--1002)); false with Invalid_argument _ -> true + combine [1;2;3] [3;2;1] = List.combine [1;2;3] [3;2;1] + combine (1 -- 100_000) (1 -- 100_000) = List.combine (1 -- 100_000) (1 -- 100_000) +*) + let return x = [x] let (>>=) l f = flat_map f l diff --git a/src/core/CCList.mli b/src/core/CCList.mli index e8a06c5c..1c7489de 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -72,6 +72,10 @@ val init : int -> (int -> 'a) -> 'a t (** Similar to {!Array.init} @since 0.6 *) +val combine : ('a list) -> ('b list) -> ('a * 'b) list +(** Similar to {!List.combine} but tail-recursive + @since NEXT_RELEASE *) + val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool