Skip to content

Commit

Permalink
feat: add is_empty, find_index, find_mapi (#21)
Browse files Browse the repository at this point in the history
These functions were introduced in OCaml 5.1.
  • Loading branch information
favonia authored Oct 20, 2023
1 parent 22c52bc commit 10bec85
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/BwdLabels.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ let compare_lengths = BwdNoLabels.compare_lengths

let[@inline] compare_length_with xs ~len = BwdNoLabels.compare_length_with xs len

let is_empty = BwdNoLabels.is_empty

let snoc = BwdNoLabels.snoc

let nth = BwdNoLabels.nth
Expand Down Expand Up @@ -64,8 +66,12 @@ let[@inline] find ~f = BwdNoLabels.find f

let[@inline] find_opt ~f = BwdNoLabels.find_opt f

let[@inline] find_index ~f = BwdNoLabels.find_index f

let[@inline] find_map ~f = BwdNoLabels.find_map f

let[@inline] find_mapi ~f = BwdNoLabels.find_mapi f

let[@inline] filter ~f = BwdNoLabels.filter f

let[@inline] find_all ~f = BwdNoLabels.find_all f
Expand Down
3 changes: 3 additions & 0 deletions src/BwdLabels.mli
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type 'a t = 'a BwdDef.bwd =
val length : 'a t -> int
val compare_lengths : 'a t -> 'a t -> int
val compare_length_with : 'a t -> len:int -> int
val is_empty : 'a t -> bool
val snoc : 'a t -> 'a -> 'a t
val nth : 'a t -> int -> 'a
val nth_opt : 'a t -> int -> 'a option
Expand Down Expand Up @@ -97,7 +98,9 @@ val memq : 'a -> set:'a t -> bool

val find : f:('a -> bool) -> 'a t -> 'a
val find_opt : f:('a -> bool) -> 'a t -> 'a option
val find_index : f:('a -> bool) -> 'a t -> int option
val find_map : f:('a -> 'b option) -> 'a t -> 'b option
val find_mapi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
val filter : f:('a -> bool) -> 'a t -> 'a t
val find_all : f:('a -> bool) -> 'a t -> 'a t
val filteri : f:(int -> 'a -> bool) -> 'a t -> 'a t
Expand Down
22 changes: 21 additions & 1 deletion src/BwdNoLabels.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ let compare_length_with xs len =
(go[@tailcall]) (len-1) xs
in go len xs

let is_empty = function Emp -> true | _ -> false

let snoc l x = Snoc (l, x)

let nth xs i =
Expand Down Expand Up @@ -270,16 +272,34 @@ let find_opt f =
if f x then Some x else go xs
in go

let find_index f =
let rec go i =
function
| Emp -> None
| Snoc (xs, x) ->
if f x then Some i else go (i+1) xs
in go 0

let find_map f =
let rec go =
function
| Emp -> None
| Snoc (xs, x) ->
match f x with
| Some y -> Some y
| Some _ as r -> r
| None -> go xs
in go

let find_mapi f =
let rec go i =
function
| Emp -> None
| Snoc (xs, x) ->
match f i x with
| Some _ as r -> r
| None -> go (i+1) xs
in go 0

let filter f =
let[@tail_mod_cons] rec go =
function
Expand Down
3 changes: 3 additions & 0 deletions src/BwdNoLabels.mli
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type 'a t = 'a BwdDef.bwd =
val length : 'a t -> int
val compare_lengths : 'a t -> 'a t -> int
val compare_length_with : 'a t -> int -> int
val is_empty : 'a t -> bool
val snoc : 'a t -> 'a -> 'a t
val nth : 'a t -> int -> 'a
val nth_opt : 'a t -> int -> 'a option
Expand Down Expand Up @@ -97,7 +98,9 @@ val memq : 'a -> 'a t -> bool

val find : ('a -> bool) -> 'a t -> 'a
val find_opt : ('a -> bool) -> 'a t -> 'a option
val find_index : ('a -> bool) -> 'a t -> int option
val find_map : ('a -> 'b option) -> 'a t -> 'b option
val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option
val filter : ('a -> bool) -> 'a t -> 'a t
val find_all : ('a -> bool) -> 'a t -> 'a t
val filteri : (int -> 'a -> bool) -> 'a t -> 'a t
Expand Down
6 changes: 6 additions & 0 deletions test/ListAsBwdLabels.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ let compare_lengths = L.compare_lengths

let compare_length_with = L.compare_length_with

let is_empty l = l = []

let snoc l x = l @ [x]

let nth xs i =
Expand Down Expand Up @@ -83,8 +85,12 @@ let find ~f xs = L.find ~f (L.rev xs)

let find_opt ~f xs = L.find_opt ~f (L.rev xs)

let find_index ~f xs = L.find_map ~f:Fun.id (L.mapi ~f:(fun i x -> if f x then Some i else None) (L.rev xs))

let find_map ~f xs = L.find_map ~f (L.rev xs)

let find_mapi ~f xs = L.find_map ~f:Fun.id (L.mapi ~f (L.rev xs))

let filter ~f xs = L.rev (L.filter ~f (L.rev xs))

let find_all ~f xs = L.rev (L.find_all ~f (L.rev xs))
Expand Down
18 changes: 18 additions & 0 deletions test/TestBwdLabels.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ let test_compare_length_with =
Q.Gen.(pair (small_list unit) (small_signed_int))
~print:Q.Print.(pair (list unit) int)
(fun (xs, len) -> B.compare_length_with (of_list xs) ~len = L.compare_length_with xs ~len)
let test_is_empty =
Q.Test.make ~count ~name:"is_empty"
Q.Gen.(small_list unit)
~print:Q.Print.(list unit)
(fun xs -> B.is_empty (of_list xs) = L.is_empty xs)
let test_snoc =
Q.Test.make ~count ~name:"snoc" Q.Gen.(pair (small_list int) int) ~print:Q.Print.(pair (list int) int)
(fun (xs, x) -> to_list (B.snoc (of_list xs) x) = L.snoc xs x)
Expand Down Expand Up @@ -208,11 +213,21 @@ let test_find_opt =
Q.Gen.(pair (Q.fun1 Q.Observable.int bool) (small_list int))
~print:Q.Print.(pair Q.Fn.print (list int))
(fun (Fun (_, f), xs) -> B.find_opt ~f (of_list xs) = L.find_opt ~f xs)
let test_find_index =
Q.Test.make ~count ~name:"find_index"
Q.Gen.(pair (Q.fun1 Q.Observable.int bool) (small_list int))
~print:Q.Print.(pair Q.Fn.print (list int))
(fun (Fun (_, f), xs) -> B.find_index ~f (of_list xs) = L.find_index ~f xs)
let test_find_map =
Q.Test.make ~count ~name:"find_map"
Q.Gen.(pair (Q.fun1 Q.Observable.int (opt int)) (small_list int))
~print:Q.Print.(pair Q.Fn.print (list int))
(fun (Fun (_, f), xs) -> B.find_map ~f (of_list xs) = L.find_map ~f xs)
let test_find_mapi =
Q.Test.make ~count ~name:"find_mapi"
Q.Gen.(pair (Q.fun2 Q.Observable.int Q.Observable.int (opt int)) (small_list int))
~print:Q.Print.(pair Q.Fn.print (list int))
(fun (Fun (_, f), xs) -> B.find_mapi ~f (of_list xs) = L.find_mapi ~f xs)
let test_filter =
Q.Test.make ~count ~name:"filter"
Q.Gen.(pair (Q.fun1 Q.Observable.int bool) (small_list int))
Expand Down Expand Up @@ -301,6 +316,7 @@ let () =
test_length;
test_compare_lengths;
test_compare_length_with;
test_is_empty;
test_snoc;
test_nth;
test_nth_opt;
Expand Down Expand Up @@ -329,7 +345,9 @@ let () =
test_memq;
test_find;
test_find_opt;
test_find_index;
test_find_map;
test_find_mapi;
test_filter;
test_find_all;
test_filteri;
Expand Down

0 comments on commit 10bec85

Please sign in to comment.