use labels in combinators that have at least two arguments, when it makes sense

This commit is contained in:
Simon Cruanes 2015-01-10 21:11:01 +01:00
parent 9a198455df
commit 61afcb8c2a
3 changed files with 81 additions and 79 deletions

View file

@ -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

View file

@ -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] *)

View file

@ -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);
()