199 lines
3.7 KiB
OCaml
199 lines
3.7 KiB
OCaml
open! Import
|
|
|
|
module type S = Indexed_container.S1 with type 'a t = 'a list
|
|
|
|
module This_list : S = struct
|
|
include List
|
|
|
|
include Indexed_container.Make (struct
|
|
type 'a t = 'a list
|
|
|
|
let fold = List.fold
|
|
let iter = `Custom List.iter
|
|
let length = `Custom List.length
|
|
let foldi = `Define_using_fold
|
|
let iteri = `Define_using_fold
|
|
end)
|
|
end
|
|
|
|
module That_list : S = List
|
|
|
|
let examples = [ []; [ 1 ]; [ 2; 3 ]; [ 4; 5; 1 ]; List.init 8 ~f:(fun i -> i * i) ]
|
|
|
|
module type Output = sig
|
|
type t [@@deriving compare, sexp_of]
|
|
end
|
|
|
|
module Int_list = struct
|
|
type t = int list [@@deriving compare, sexp_of]
|
|
end
|
|
|
|
module Int_pair_option = struct
|
|
type t = (int * int) option [@@deriving compare, sexp_of]
|
|
end
|
|
|
|
module Int_option = struct
|
|
type t = int option [@@deriving compare, sexp_of]
|
|
end
|
|
|
|
let check (type a) here examples ~actual ~expect (module Output : Output with type t = a) =
|
|
List.iter examples ~f:(fun example ->
|
|
let actual = actual example in
|
|
let expect = expect example in
|
|
require
|
|
here
|
|
(Output.compare actual expect = 0)
|
|
~if_false_then_print_s:(lazy [%message (expect : Output.t)]);
|
|
print_s [%sexp (actual : Output.t)])
|
|
;;
|
|
|
|
let%expect_test "foldi" =
|
|
let f i acc elt = if i % 2 = 0 then elt :: acc else acc in
|
|
check
|
|
[%here]
|
|
examples
|
|
(module Int_list)
|
|
~actual:(fun list -> This_list.foldi list ~init:[] ~f)
|
|
~expect:(fun list -> That_list.foldi list ~init:[] ~f);
|
|
[%expect {|
|
|
()
|
|
(1)
|
|
(2)
|
|
(1 4)
|
|
(36 16 4 0)
|
|
|}]
|
|
;;
|
|
|
|
let%expect_test "findi" =
|
|
let check f =
|
|
check
|
|
[%here]
|
|
examples
|
|
(module Int_pair_option)
|
|
~actual:(fun list -> This_list.findi list ~f)
|
|
~expect:(fun list -> That_list.findi list ~f)
|
|
in
|
|
check (fun i _elt -> i = 0);
|
|
[%expect {|
|
|
()
|
|
((0 1))
|
|
((0 2))
|
|
((0 4))
|
|
((0 0))
|
|
|}];
|
|
check (fun _i elt -> elt = 1);
|
|
[%expect {|
|
|
()
|
|
((0 1))
|
|
()
|
|
((2 1))
|
|
((1 1))
|
|
|}]
|
|
;;
|
|
|
|
let%expect_test "find_mapi" =
|
|
let f i elt = if elt = 1 then Some ((i * 100) + elt) else None in
|
|
check
|
|
[%here]
|
|
examples
|
|
(module Int_option)
|
|
~actual:(fun list -> This_list.find_mapi list ~f)
|
|
~expect:(fun list -> That_list.find_mapi list ~f);
|
|
[%expect {|
|
|
()
|
|
(1)
|
|
()
|
|
(201)
|
|
(101)
|
|
|}]
|
|
;;
|
|
|
|
let%expect_test "iteri" =
|
|
let go iteri =
|
|
let acc = ref [] in
|
|
iteri ~f:(fun i elt -> acc := i :: elt :: !acc);
|
|
!acc
|
|
in
|
|
check
|
|
[%here]
|
|
examples
|
|
(module Int_list)
|
|
~actual:(fun list -> go (This_list.iteri list))
|
|
~expect:(fun list -> go (That_list.iteri list));
|
|
[%expect
|
|
{|
|
|
()
|
|
(0 1)
|
|
(1 3 0 2)
|
|
(2 1 1 5 0 4)
|
|
(7 49 6 36 5 25 4 16 3 9 2 4 1 1 0 0)
|
|
|}]
|
|
;;
|
|
|
|
let bool_examples =
|
|
[ []
|
|
; [ true ]
|
|
; [ false ]
|
|
; [ false; false ]
|
|
; [ true; false ]
|
|
; [ false; true ]
|
|
; [ true; true ]
|
|
]
|
|
;;
|
|
|
|
let%expect_test "for_alli" =
|
|
let f _i elt = elt in
|
|
check
|
|
[%here]
|
|
bool_examples
|
|
(module Bool)
|
|
~actual:(fun list -> This_list.for_alli list ~f)
|
|
~expect:(fun list -> That_list.for_alli list ~f);
|
|
[%expect {|
|
|
true
|
|
true
|
|
false
|
|
false
|
|
false
|
|
false
|
|
true
|
|
|}]
|
|
;;
|
|
|
|
let%expect_test "existsi" =
|
|
let f _i elt = elt in
|
|
check
|
|
[%here]
|
|
bool_examples
|
|
(module Bool)
|
|
~actual:(fun list -> This_list.existsi list ~f)
|
|
~expect:(fun list -> That_list.existsi list ~f);
|
|
[%expect {|
|
|
false
|
|
true
|
|
false
|
|
false
|
|
true
|
|
true
|
|
true
|
|
|}]
|
|
;;
|
|
|
|
let%expect_test "counti" =
|
|
let f _i elt = elt in
|
|
check
|
|
[%here]
|
|
bool_examples
|
|
(module Int)
|
|
~actual:(fun list -> This_list.counti list ~f)
|
|
~expect:(fun list -> That_list.counti list ~f);
|
|
[%expect {|
|
|
0
|
|
1
|
|
0
|
|
0
|
|
1
|
|
1
|
|
2
|
|
|}]
|
|
;;
|