Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add is_empty, find_index, find_mapi #21

Merged
merged 2 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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