Merge pull request #138 from bikalgurung/master

Implement safe version of `List.split` (thanks to @bikalgurung)
This commit is contained in:
Simon Cruanes 2017-06-29 23:34:53 +02:00 committed by GitHub
commit 887d2f5d8d
3 changed files with 49 additions and 1 deletions

View file

@ -20,4 +20,5 @@
- David Sheets (@dsheets)
- Glenn Slotte (glennsl)
- @LemonBoy
- Leonid Rozenberg (@rleonid)
- Leonid Rozenberg (@rleonid)
- Bikal Gurung (@bikalgurung)

View file

@ -387,6 +387,48 @@ let combine_gen l1 l2 =
res1 = res2)
*)
let split l =
let rec direct i l = match l with
| [] -> ([],[])
| [x1, y1] -> [x1], [y1]
| [x1, y1; x2, y2] -> [x1;x2], [y1;y2]
| [x1, y1; x2, y2; x3, y3] -> [x1;x2;x3], [y1;y2;y3]
| [x1, y1; x2, y2; x3, y3; x4, y4] -> [x1;x2;x3;x4], [y1;y2;y3;y4]
| _ when i=0 -> split_slow ([], []) l
| (x1, y1) ::
(x2, y2) ::
(x3, y3) ::
(x4, y4) ::
(x5, y5) :: l' ->
let rx, ry = direct (i-1) l'
in
(x1 :: x2 :: x3 :: x4 :: x5 :: rx,
y1 :: y2 :: y3 :: y4 :: y5 :: ry)
and split_slow acc l = match l with
| [] -> acc
| (x1, y1) :: l' ->
let acc = (x1 :: fst acc, y1 :: snd acc)
in
split_slow acc l'
in
direct direct_depth_default_ l
(*$Q
(Q.(list (pair int string))) (fun l -> \
let (l1, l2) = split l in \
List.length l1 = List.length l \
&& List.length l2 = List.length l)
(Q.(list (pair string int))) (fun l -> \
let l = ("hello", 10) :: l in \
let (l1, l2) = split l in \
let i = Random.int @@ List.length l in \
let l1_x = List.nth l1 i in \
let l2_y = List.nth l2 i in \
let (x,y) = List.nth l i in \
l1_x = x && l2_y = y)
*)
let return x = [x]
let (>>=) l f = flat_map f l

View file

@ -92,6 +92,9 @@ val combine_gen : 'a list -> 'b list -> ('a * 'b) gen
instead, the output has as many pairs as the smallest input list.
@since 1.2 *)
val split : ('a * 'b) t -> 'a t * 'b t
(** A tail-recursive version of {!List.split}. *)
val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
@ -518,3 +521,5 @@ end
val pp : ?start:string -> ?stop:string -> ?sep:string ->
'a printer -> 'a t printer
(** {2 Lists of pairs} *)