diff --git a/sequence.ml b/sequence.ml index 2fefe5f..676ed0a 100644 --- a/sequence.ml +++ b/sequence.ml @@ -63,21 +63,21 @@ let rec forever f k = let cycle s k = while true do s k; done -let iter f seq = seq f +let iter ~(f:'a -> unit) seq = seq f -let iteri f seq = +let iteri ~f seq = let r = ref 0 in seq (fun x -> f !r x; incr r) -let fold f init seq = +let fold ~f ~init seq = let r = ref init in seq (fun elt -> r := f !r elt); !r -let foldi f init seq = +let foldi ~f ~init seq = let i = ref 0 in let r = ref init in seq @@ -86,13 +86,13 @@ let foldi f init seq = incr i); !r -let map f seq k = seq (fun x -> k (f x)) +let map ~f seq k = seq (fun x -> k (f x)) -let mapi f seq k = +let mapi ~f seq k = let i = ref 0 in seq (fun x -> k (f !i x); incr i) -let filter p seq k = seq (fun x -> if p x then k x) +let filter ~f seq k = seq (fun x -> if f x then k x) let append s1 s2 k = s1 k; s2 k @@ -100,11 +100,11 @@ let concat s k = s (fun s' -> s' k) let flatten s = concat s -let flatMap f seq k = seq (fun x -> f x k) +let flatMap ~f seq k = seq (fun x -> f x k) let flat_map = flatMap -let fmap f seq k = +let fmap ~f seq k = seq (fun x -> match f x with | None -> () | Some y -> k y @@ -112,9 +112,9 @@ let fmap f seq k = let filter_map = fmap -let intersperse elem seq k = +let intersperse ~x seq k = let first = ref true in - seq (fun x -> (if !first then first := false else k elem); k x) + seq (fun y -> (if !first then first := false else k x); k y) (** Mutable unrolled list to serve as intermediate storage *) module MList = struct @@ -234,7 +234,7 @@ let persistent_lazy (seq:'a t) = let sort ?(cmp=Pervasives.compare) seq = (* use an intermediate list, then sort the list *) - let l = fold (fun l x -> x::l) [] seq in + let l = fold ~f:(fun l x -> x::l) ~init:[] seq in let l = List.fast_sort cmp l in fun k -> List.iter k l @@ -268,7 +268,7 @@ let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq = type t = elt let compare = cmp end) in - let set = fold (fun acc x -> S.add x acc) S.empty seq in + let set = fold ~f:(fun acc x -> S.add x acc) ~init:S.empty seq in fun k -> S.iter k set let product outer inner k = @@ -342,15 +342,15 @@ let take n seq k = exception ExitTakeWhile -let take_while p seq k = +let take_while ~f seq k = try - seq (fun x -> if p x then k x else raise ExitTakeWhile) + seq (fun x -> if f x then k x else raise ExitTakeWhile) with ExitTakeWhile -> () exception ExitFoldWhile -let fold_while f s seq = - let state = ref s in +let fold_while ~f ~init seq = + let state = ref init in let consume x = let acc, cont = f (!state) x in state := acc; @@ -366,11 +366,11 @@ let drop n seq k = let count = ref 0 in seq (fun x -> if !count >= n then k x else incr count) -let drop_while p seq k = +let drop_while ~f seq k = let drop = ref true in seq (fun x -> if !drop - then if p x then () else (drop := false; k x) + then if f x then () else (drop := false; k x) else k x) let rev seq = @@ -379,26 +379,26 @@ let rev seq = exception ExitForall -let for_all p seq = +let for_all ~f seq = try - seq (fun x -> if not (p x) then raise ExitForall); + seq (fun x -> if not (f x) then raise ExitForall); true with ExitForall -> false exception ExitExists (** Exists there some element satisfying the predicate? *) -let exists p seq = +let exists ~f seq = try - seq (fun x -> if p x then raise ExitExists); + seq (fun x -> if f x then raise ExitExists); false with ExitExists -> true -let mem ?(eq=(=)) x seq = exists (eq x) seq +let mem ?(eq=(=)) ~x seq = exists ~f:(eq x) seq exception ExitFind -let find f seq = +let find ~f seq = let r = ref None in begin try seq (fun x -> match f x with @@ -441,23 +441,23 @@ let zip_i seq k = let r = ref 0 in seq (fun x -> let n = !r in incr r; k n x) -let fold2 f acc seq2 = - let acc = ref acc in +let fold2 ~f ~init seq2 = + let acc = ref init in seq2 (fun x y -> acc := f !acc x y); !acc -let iter2 f seq2 = seq2 f +let iter2 ~f seq2 = seq2 f -let map2 f seq2 k = seq2 (fun x y -> k (f x y)) +let map2 ~f seq2 k = seq2 (fun x y -> k (f x y)) let map2_2 f g seq2 k = seq2 (fun x y -> k (f x y) (g x y)) (** {2 Basic data structures converters} *) -let to_list seq = List.rev (fold (fun y x -> x::y) [] seq) +let to_list seq = List.rev (fold ~f:(fun y x -> x::y) ~init:[] seq) -let to_rev_list seq = fold (fun y x -> x :: y) [] seq +let to_rev_list seq = fold ~f:(fun y x -> x :: y) ~init:[] seq let of_list l k = List.iter k l @@ -508,7 +508,7 @@ let to_stream seq = let l = MList.of_seq seq in MList.to_stream l -let to_stack s seq = iter (fun x -> Stack.push x s) seq +let to_stack s seq = iter ~f:(fun x -> Stack.push x s) seq let of_stack s k = Stack.iter k s @@ -544,12 +544,12 @@ let of_str s k = String.iter k s let to_str seq = let b = Buffer.create 64 in - iter (fun c -> Buffer.add_char b c) seq; + iter ~f:(fun c -> Buffer.add_char b c) seq; Buffer.contents b let concat_str seq = let b = Buffer.create 64 in - iter (Buffer.add_string b) seq; + iter ~f:(Buffer.add_string b) seq; Buffer.contents b exception OneShotSequence @@ -585,8 +585,8 @@ let of_set (type s) (type v) m set = let to_set (type s) (type v) m seq = let module S = (val m : Set.S with type t = s and type elt = v) in fold - (fun set x -> S.add x set) - S.empty seq + ~f:(fun set x -> S.add x set) + ~init:S.empty seq type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] @@ -627,7 +627,7 @@ module Set = struct module Adapt(X : Set.S) : S with type elt = X.elt and type t = X.t = struct let to_seq set k = X.iter k set - let of_seq seq = fold (fun set x -> X.add x set) X.empty seq + let of_seq seq = fold ~f:(fun set x -> X.add x set) ~init:X.empty seq let to_list set = to_list (to_seq set) @@ -660,7 +660,7 @@ module Map = struct module Adapt(M : Map.S) = struct let to_seq m = from_iter (fun k -> M.iter (fun x y -> k (x,y)) m) - let of_seq seq = fold (fun m (k,v) -> M.add k v m) M.empty seq + let of_seq seq = fold ~f:(fun m (k,v) -> M.add k v m) ~init:M.empty seq let keys m = from_iter (fun k -> M.iter (fun x _ -> k x) m) @@ -704,9 +704,9 @@ module Infix = struct let (--^) i j = int_range_dec ~start:i ~stop:j - let (>>=) x f = flat_map f x + let (>>=) x f = flat_map ~f x - let (>|=) x f = map f x + let (>|=) x f = map ~f x let (<*>) funs args k = funs (fun f -> args (fun x -> k (f x))) @@ -791,12 +791,12 @@ module IO = struct raise e let write_to ?mode ?flags filename seq = - write_bytes_to ?mode ?flags filename (map Bytes.unsafe_of_string seq) + write_bytes_to ?mode ?flags filename (map ~f:Bytes.unsafe_of_string seq) let write_bytes_lines ?mode ?flags filename seq = let ret = Bytes.unsafe_of_string "\n" in - write_bytes_to ?mode ?flags filename (snoc (intersperse ret seq) ret) + write_bytes_to ?mode ?flags filename (snoc (intersperse ~x:ret seq) ret) let write_lines ?mode ?flags filename seq = - write_bytes_lines ?mode ?flags filename (map Bytes.unsafe_of_string seq) + write_bytes_lines ?mode ?flags filename (map ~f:Bytes.unsafe_of_string seq) end diff --git a/sequence.mli b/sequence.mli index 7957890..0022c0d 100644 --- a/sequence.mli +++ b/sequence.mli @@ -112,37 +112,37 @@ val cycle : 'a t -> 'a t (** {2 Consume a sequence} *) -val iter : ('a -> unit) -> 'a t -> unit +val iter : f:('a -> unit) -> 'a t -> unit (** Consume the sequence, passing all its arguments to the function. Basically [iter f seq] is just [seq f]. *) -val iteri : (int -> 'a -> unit) -> 'a t -> unit +val iteri : f:(int -> 'a -> unit) -> 'a t -> unit (** Iterate on elements and their index in the sequence *) -val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a +val fold : f:('a -> 'b -> 'a) -> init:'a -> 'b t -> 'a (** Fold over elements of the sequence, consuming it *) -val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a +val foldi : f:('a -> int -> 'b -> 'a) -> init:'a -> 'b t -> 'a (** Fold over elements of the sequence and their index, consuming it *) -val map : ('a -> 'b) -> 'a t -> 'b t +val map : f:('a -> 'b) -> 'a t -> 'b t (** Map objects of the sequence into other elements, lazily *) -val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t +val mapi : f:(int -> 'a -> 'b) -> 'a t -> 'b t (** Map objects, along with their index in the sequence *) -val for_all : ('a -> bool) -> 'a t -> bool +val for_all : f:('a -> bool) -> 'a t -> bool (** Do all elements satisfy the predicate? *) -val exists : ('a -> bool) -> 'a t -> bool +val exists : f:('a -> bool) -> 'a t -> bool (** Exists there some element satisfying the predicate? *) -val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool +val mem : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> bool (** Is the value a member of the sequence? @param eq the equality predicate to use (default [(=)]) @since 0.5 *) -val find : ('a -> 'b option) -> 'a t -> 'b option +val find : f:('a -> 'b option) -> 'a t -> 'b option (** Find the first element on which the function doesn't return [None] @since 0.5 *) @@ -154,7 +154,7 @@ val is_empty : 'a t -> bool (** {2 Transform a sequence} *) -val filter : ('a -> bool) -> 'a t -> 'a t +val filter : f:('a -> bool) -> 'a t -> 'a t (** Filter on elements of the sequence *) val append : 'a t -> 'a t -> 'a t @@ -167,22 +167,24 @@ val concat : 'a t t -> 'a t val flatten : 'a t t -> 'a t (** Alias for {!concat} *) -val flatMap : ('a -> 'b t) -> 'a t -> 'b t +val flatMap : f:('a -> 'b t) -> 'a t -> 'b t (** Monadic bind. Intuitively, it applies the function to every element of the - initial sequence, and calls {!concat}. *) + initial sequence, and calls {!concat}. + @deprecated use {!flat_map} *) -val flat_map : ('a -> 'b t) -> 'a t -> 'b t +val flat_map : f:('a -> 'b t) -> 'a t -> 'b t (** Alias to {!flatMap} with a more explicit name @since 0.5 *) -val fmap : ('a -> 'b option) -> 'a t -> 'b t - (** Specialized version of {!flatMap} for options. *) +val fmap : f:('a -> 'b option) -> 'a t -> 'b t + (** Specialized version of {!flatMap} for options. + @deprecated use {!filter_map} *) -val filter_map : ('a -> 'b option) -> 'a t -> 'b t +val filter_map : f:('a -> 'b option) -> 'a t -> 'b t (** Alias to {!fmap} with a more explicit name @since 0.5 *) -val intersperse : 'a -> 'a t -> 'a t +val intersperse : x:'a -> 'a t -> 'a t (** Insert the single element between every element of the sequence *) (** {2 Caching} *) @@ -267,12 +269,12 @@ val take : int -> 'a t -> 'a t (** Take at most [n] elements from the sequence. Works on infinite sequences. *) -val take_while : ('a -> bool) -> 'a t -> 'a t +val take_while : f:('a -> bool) -> 'a t -> 'a t (** Take elements while they satisfy the predicate, then stops iterating. Will work on an infinite sequence [s] if the predicate is false for at least one element of [s]. *) -val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a +val fold_while : f:('a -> 'b -> 'a * [`Stop | `Continue]) -> init:'a -> 'b t -> 'a (** Folds over elements of the sequence, stopping early if the accumulator returns [('a, `Stop)] @since NEXT_RELEASE *) @@ -280,7 +282,7 @@ val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a val drop : int -> 'a t -> 'a t (** Drop the [n] first elements of the sequence. Lazy. *) -val drop_while : ('a -> bool) -> 'a t -> 'a t +val drop_while : f:('a -> bool) -> 'a t -> 'a t (** Predicate version of {!drop} *) val rev : 'a t -> 'a t @@ -303,11 +305,11 @@ val unzip : ('a * 'b) t -> ('a, 'b) t2 val zip_i : 'a t -> (int, 'a) t2 (** Zip elements of the sequence with their index in the sequence *) -val fold2 : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t2 -> 'c +val fold2 : f:('c -> 'a -> 'b -> 'c) -> init:'c -> ('a, 'b) t2 -> 'c -val iter2 : ('a -> 'b -> unit) -> ('a, 'b) t2 -> unit +val iter2 : f:('a -> 'b -> unit) -> ('a, 'b) t2 -> unit -val map2 : ('a -> 'b -> 'c) -> ('a, 'b) t2 -> 'c t +val map2 : f:('a -> 'b -> 'c) -> ('a, 'b) t2 -> 'c t val map2_2 : ('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a, 'b) t2 -> ('c, 'd) t2 (** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *) diff --git a/tests/test_sequence.ml b/tests/test_sequence.ml index 8fd1b17..734f1d4 100644 --- a/tests/test_sequence.ml +++ b/tests/test_sequence.ml @@ -13,7 +13,7 @@ let test_empty () = let seq = S.empty in OUnit.assert_bool "empty" (S.is_empty seq); OUnit.assert_bool "empty" - (try S.iter (fun _ -> raise Exit) seq; true with Exit -> false); + (try S.iter ~f:(fun _ -> raise Exit) seq; true with Exit -> false); () let test_repeat () = @@ -31,29 +31,29 @@ let test_concat () = let test_fold () = let n = S.(1 -- 10) - |> S.fold (+) 0 in + |> S.fold ~f:(+) ~init:0 in OUnit.assert_equal 55 n; () let test_foldi () = let l = ["hello"; "world"] |> S.of_list - |> S.foldi (fun acc i x -> (i,x) :: acc) [] in + |> S.foldi ~f:(fun acc i x -> (i,x) :: acc) ~init:[] in OUnit.assert_equal [1, "world"; 0, "hello"] l; () let test_fold_while () = let n = S.of_list [true;true;false;true] - |> S.fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 in + |> S.fold_while ~f:(fun acc b -> if b then acc+1, `Continue else acc, `Stop) ~init:0 in OUnit.assert_equal 2 n; () let test_exists () = S.(1 -- 100) - |> S.exists (fun x -> x = 59) + |> S.exists ~f:(fun x -> x = 59) |> OUnit.assert_bool "exists"; S.(1 -- 100) - |> S.exists (fun x -> x < 0) + |> S.exists ~f:(fun x -> x < 0) |> (fun x -> not x) |> OUnit.assert_bool "not exists"; () @@ -63,20 +63,20 @@ let test_length () = let test_concat2 () = S.(1 -- 1000) - |> S.map (fun i -> S.(i -- (i+1))) + |> S.map ~f:(fun i -> S.(i -- (i+1))) |> S.concat |> S.length |> OUnit.assert_equal 2000 let test_flatMap () = S.(1 -- 1000) - |> S.flatMap (fun i -> S.(i -- (i+1))) + |> S.flat_map ~f:(fun i -> S.(i -- (i+1))) |> S.length |> OUnit.assert_equal 2000 let test_intersperse () = S.(1 -- 100) - |> (fun seq -> S.intersperse 0 seq) + |> (fun seq -> S.intersperse ~x:0 seq) |> S.take 10 |> S.to_list |> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0] @@ -138,7 +138,7 @@ let test_product () = let stream = Stream.from (fun i -> if i < 3 then Some i else None) in let a = S.of_stream stream in let b = S.of_list ["a";"b";"c"] in - let s = S.product a b |> S.map (fun (x,y) -> y,x) + let s = S.product a b |> S.map ~f:(fun (x,y) -> y,x) |> S.to_list |> List.sort compare in OUnit.assert_equal ["a",0; "a", 1; "a", 2; "b",0; "b", 1; "b", 2; @@ -177,14 +177,14 @@ let test_hashtbl () = |> S.zip_i |> S.to_hashtbl2 in S.(0 -- 4) - |> S.iter (fun i -> OUnit.assert_equal (i+1) (Hashtbl.find h i)); + |> S.iter ~f:(fun i -> OUnit.assert_equal (i+1) (Hashtbl.find h i)); OUnit.assert_equal [0;1;2;3;4] (S.hashtbl_keys h |> S.sort ?cmp:None |> S.to_list); () let test_buff () = let b = Buffer.create 4 in "hello world" - |> S.of_str |> S.rev |> S.map Char.uppercase + |> S.of_str |> S.rev |> S.map ~f:Char.uppercase |> (fun seq -> S.to_buffer seq b); OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b); ()