Skip to content

Commit

Permalink
feat: make partition and partition_map tail-recursive (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
favonia authored Oct 22, 2023
1 parent 1babd01 commit 89710d7
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 22 deletions.
2 changes: 0 additions & 2 deletions src/BwdLabels.mli
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,8 @@ val find_all : f:('a -> bool) -> 'a t -> 'a t

val filteri : f:(int -> 'a -> bool) -> 'a t -> 'a t

(** Not tail-recursive. *)
val partition : f:('a -> bool) -> 'a t -> 'a t * 'a t

(** Not tail-recursive. *)
val partition_map : f:('a -> ('b, 'c) Either.t) -> 'a t -> 'b t * 'c t

(** {1 Lists of pairs} *)
Expand Down
32 changes: 14 additions & 18 deletions src/BwdNoLabels.ml
Original file line number Diff line number Diff line change
Expand Up @@ -324,32 +324,28 @@ let filteri f =
(go[@tailcall]) (i + 1) xs
in go 0

let partition f =
let rec go =
function
| Emp -> Emp, Emp
let partition f xs =
let rec go xs ys zs =
match xs with
| Emp -> append Emp ys, append Emp zs
| Snoc (xs, x) ->
if f x then
let ys, zs = go xs in
Snoc (ys, x), zs
(go[@tailcall]) xs (x :: ys) zs
else
let ys, zs = go xs in
ys, Snoc (zs, x)
in go
(go[@tailcall]) xs ys (x :: zs)
in go xs [] []

let partition_map f =
let rec go =
function
| Emp -> Emp, Emp
let partition_map f xs =
let rec go xs ys zs =
match xs with
| Emp -> append Emp ys, append Emp zs
| Snoc (xs, x) ->
match f x with
| Either.Left y ->
let ys, zs = go xs in
Snoc (ys, y), zs
(go[@tailcall]) xs (y :: ys) zs
| Either.Right z ->
let ys, zs = go xs in
ys, Snoc (zs, z)
in go
(go[@tailcall]) xs ys (z :: zs)
in go xs [] []

let rec split =
function
Expand Down
2 changes: 0 additions & 2 deletions src/BwdNoLabels.mli
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,8 @@ val find_all : ('a -> bool) -> 'a t -> 'a t

val filteri : (int -> 'a -> bool) -> 'a t -> 'a t

(** Not tail-recursive. *)
val partition : ('a -> bool) -> 'a t -> 'a t * 'a t

(** Not tail-recursive. *)
val partition_map : ('a -> ('b, 'c) Either.t) -> 'a t -> 'b t * 'c t

(** {1 Lists of pairs} *)
Expand Down

0 comments on commit 89710d7

Please sign in to comment.