mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 11:15:32 -05:00
Merge branch 'master' into stable for 0.11
This commit is contained in:
commit
26bb1617fb
20 changed files with 341 additions and 111 deletions
2
.merlin
2
.merlin
|
|
@ -7,4 +7,4 @@ B _build/bench/
|
||||||
PKG oUnit qcheck
|
PKG oUnit qcheck
|
||||||
PKG benchmark
|
PKG benchmark
|
||||||
FLG -safe-string
|
FLG -safe-string
|
||||||
FLG -w +a -w -4 -w -44
|
FLG -w+a-4-44-48-60@8
|
||||||
|
|
|
||||||
1
Makefile
1
Makefile
|
|
@ -97,6 +97,7 @@ release:
|
||||||
watch:
|
watch:
|
||||||
while find src/ -print0 | xargs -0 inotifywait -e delete_self -e modify ; do \
|
while find src/ -print0 | xargs -0 inotifywait -e delete_self -e modify ; do \
|
||||||
echo "============ at `date` ==========" ; \
|
echo "============ at `date` ==========" ; \
|
||||||
|
sleep 0.2; \
|
||||||
make all; \
|
make all; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
||||||
2
_oasis
2
_oasis
|
|
@ -1,6 +1,6 @@
|
||||||
OASISFormat: 0.4
|
OASISFormat: 0.4
|
||||||
Name: sequence
|
Name: sequence
|
||||||
Version: 0.10
|
Version: 0.11
|
||||||
Homepage: https://github.com/c-cube/sequence
|
Homepage: https://github.com/c-cube/sequence
|
||||||
Authors: Simon Cruanes
|
Authors: Simon Cruanes
|
||||||
License: BSD-2-clause
|
License: BSD-2-clause
|
||||||
|
|
|
||||||
7
_tags
7
_tags
|
|
@ -50,8 +50,9 @@ true: annot, bin_annot
|
||||||
<bench/*.ml{,i,y}>: pkg_bytes
|
<bench/*.ml{,i,y}>: pkg_bytes
|
||||||
<bench/*.ml{,i,y}>: use_sequence
|
<bench/*.ml{,i,y}>: use_sequence
|
||||||
# OASIS_STOP
|
# OASIS_STOP
|
||||||
true: bin_annot
|
true: safe_string, bin_annot, color(always)
|
||||||
<**/*.ml>: warn_A, warn(-4)
|
<**/*.ml>: warn(+a-4-44-48@8)
|
||||||
|
<src/bigarray/*.ml>: warn(-33)
|
||||||
true: mark_tag_used
|
true: mark_tag_used
|
||||||
<**/*.cmx>: optimize(3)
|
<**/*.cmx>: optimize(3)
|
||||||
<src/sequenceLabels.cm*>: nolabels
|
<src/*Labels.cm*>: nolabels
|
||||||
|
|
|
||||||
6
descr
6
descr
|
|
@ -1,6 +0,0 @@
|
||||||
Simple and lightweight sequence abstract data type.
|
|
||||||
|
|
||||||
Simple sequence abstract data type, intended to transfer a finite number of
|
|
||||||
elements from one data structure to another. Some transformations on sequences,
|
|
||||||
like `filter`, `map`, `take`, `drop` and `append` can be performed before the
|
|
||||||
sequence is iterated/folded on.
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
(* OASIS_START *)
|
(* OASIS_START *)
|
||||||
(* DO NOT EDIT (digest: 25607cca926d807aaffd1aa7d72d57d9) *)
|
(* DO NOT EDIT (digest: df4781680e858ab0acccf45efeb50c19) *)
|
||||||
module OASISGettext = struct
|
module OASISGettext = struct
|
||||||
(* # 22 "src/oasis/OASISGettext.ml" *)
|
(* # 22 "src/oasis/OASISGettext.ml" *)
|
||||||
|
|
||||||
|
|
@ -105,10 +105,7 @@ module OASISString = struct
|
||||||
ok := false;
|
ok := false;
|
||||||
incr str_idx
|
incr str_idx
|
||||||
done;
|
done;
|
||||||
if !what_idx = String.length what then
|
!what_idx = String.length what
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
|
|
||||||
|
|
||||||
let strip_starts_with ~what str =
|
let strip_starts_with ~what str =
|
||||||
|
|
@ -131,10 +128,7 @@ module OASISString = struct
|
||||||
ok := false;
|
ok := false;
|
||||||
decr str_idx
|
decr str_idx
|
||||||
done;
|
done;
|
||||||
if !what_idx = -1 then
|
!what_idx = -1
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
|
|
||||||
|
|
||||||
let strip_ends_with ~what str =
|
let strip_ends_with ~what str =
|
||||||
|
|
@ -440,7 +434,7 @@ module OASISExpr = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 443 "myocamlbuild.ml"
|
# 437 "myocamlbuild.ml"
|
||||||
module BaseEnvLight = struct
|
module BaseEnvLight = struct
|
||||||
(* # 22 "src/base/BaseEnvLight.ml" *)
|
(* # 22 "src/base/BaseEnvLight.ml" *)
|
||||||
|
|
||||||
|
|
@ -520,7 +514,7 @@ module BaseEnvLight = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 523 "myocamlbuild.ml"
|
# 517 "myocamlbuild.ml"
|
||||||
module MyOCamlbuildFindlib = struct
|
module MyOCamlbuildFindlib = struct
|
||||||
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
|
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
|
||||||
|
|
||||||
|
|
@ -881,7 +875,7 @@ module MyOCamlbuildBase = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 884 "myocamlbuild.ml"
|
# 878 "myocamlbuild.ml"
|
||||||
open Ocamlbuild_plugin;;
|
open Ocamlbuild_plugin;;
|
||||||
let package_default =
|
let package_default =
|
||||||
{
|
{
|
||||||
|
|
@ -907,6 +901,6 @@ let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
|
||||||
|
|
||||||
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
|
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
|
||||||
|
|
||||||
# 911 "myocamlbuild.ml"
|
# 905 "myocamlbuild.ml"
|
||||||
(* OASIS_STOP *)
|
(* OASIS_STOP *)
|
||||||
Ocamlbuild_plugin.dispatch dispatch_default;;
|
Ocamlbuild_plugin.dispatch dispatch_default;;
|
||||||
|
|
|
||||||
5
opam
5
opam
|
|
@ -1,13 +1,14 @@
|
||||||
opam-version: "1.2"
|
opam-version: "1.2"
|
||||||
name: "sequence"
|
name: "sequence"
|
||||||
version: "0.10"
|
version: "0.11"
|
||||||
author: "Simon Cruanes"
|
author: "Simon Cruanes"
|
||||||
maintainer: "simon.cruanes@inria.fr"
|
maintainer: "simon.cruanes.2007@m4x.org"
|
||||||
license: "BSD-2-clauses"
|
license: "BSD-2-clauses"
|
||||||
build: [
|
build: [
|
||||||
["./configure" "--disable-docs"
|
["./configure" "--disable-docs"
|
||||||
"--%{delimcc:enable}%-invert"
|
"--%{delimcc:enable}%-invert"
|
||||||
"--%{base-bigarray:enable}%-bigarray"
|
"--%{base-bigarray:enable}%-bigarray"
|
||||||
|
"--prefix" "%{prefix}%"
|
||||||
]
|
]
|
||||||
[make "build"]
|
[make "build"]
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 8c0ffebbdb3e063d4b3e5cc00517b199)
|
|
||||||
Sequence
|
|
||||||
SequenceLabels
|
|
||||||
# OASIS_STOP
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# OASIS_START
|
|
||||||
# DO NOT EDIT (digest: 8c0ffebbdb3e063d4b3e5cc00517b199)
|
|
||||||
Sequence
|
|
||||||
SequenceLabels
|
|
||||||
# OASIS_STOP
|
|
||||||
58
setup.ml
58
setup.ml
|
|
@ -1,9 +1,9 @@
|
||||||
(* setup.ml generated for the first time by OASIS v0.4.4 *)
|
(* setup.ml generated for the first time by OASIS v0.4.4 *)
|
||||||
|
|
||||||
(* OASIS_START *)
|
(* OASIS_START *)
|
||||||
(* DO NOT EDIT (digest: b6facd5b08b6b1360edc26bd90d50fa3) *)
|
(* DO NOT EDIT (digest: b51801b110892305c8a99f1b01e7fcf0) *)
|
||||||
(*
|
(*
|
||||||
Regenerated by OASIS v0.4.8
|
Regenerated by OASIS v0.4.10
|
||||||
Visit http://oasis.forge.ocamlcore.org for more information and
|
Visit http://oasis.forge.ocamlcore.org for more information and
|
||||||
documentation about functions used in this file.
|
documentation about functions used in this file.
|
||||||
*)
|
*)
|
||||||
|
|
@ -112,10 +112,7 @@ module OASISString = struct
|
||||||
ok := false;
|
ok := false;
|
||||||
incr str_idx
|
incr str_idx
|
||||||
done;
|
done;
|
||||||
if !what_idx = String.length what then
|
!what_idx = String.length what
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
|
|
||||||
|
|
||||||
let strip_starts_with ~what str =
|
let strip_starts_with ~what str =
|
||||||
|
|
@ -138,10 +135,7 @@ module OASISString = struct
|
||||||
ok := false;
|
ok := false;
|
||||||
decr str_idx
|
decr str_idx
|
||||||
done;
|
done;
|
||||||
if !what_idx = -1 then
|
!what_idx = -1
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
|
|
||||||
|
|
||||||
let strip_ends_with ~what str =
|
let strip_ends_with ~what str =
|
||||||
|
|
@ -3162,7 +3156,7 @@ module OASISFileUtil = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 3165 "setup.ml"
|
# 3159 "setup.ml"
|
||||||
module BaseEnvLight = struct
|
module BaseEnvLight = struct
|
||||||
(* # 22 "src/base/BaseEnvLight.ml" *)
|
(* # 22 "src/base/BaseEnvLight.ml" *)
|
||||||
|
|
||||||
|
|
@ -3242,7 +3236,7 @@ module BaseEnvLight = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 3245 "setup.ml"
|
# 3239 "setup.ml"
|
||||||
module BaseContext = struct
|
module BaseContext = struct
|
||||||
(* # 22 "src/base/BaseContext.ml" *)
|
(* # 22 "src/base/BaseContext.ml" *)
|
||||||
|
|
||||||
|
|
@ -5665,7 +5659,7 @@ module BaseCompat = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 5668 "setup.ml"
|
# 5662 "setup.ml"
|
||||||
module InternalConfigurePlugin = struct
|
module InternalConfigurePlugin = struct
|
||||||
(* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
|
(* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
|
||||||
|
|
||||||
|
|
@ -6016,17 +6010,14 @@ module InternalInstallPlugin = struct
|
||||||
|
|
||||||
let install =
|
let install =
|
||||||
|
|
||||||
let in_destdir =
|
let in_destdir fn =
|
||||||
try
|
try
|
||||||
let destdir =
|
(* Practically speaking destdir is prepended at the beginning of the
|
||||||
destdir ()
|
target filename
|
||||||
in
|
*)
|
||||||
(* Practically speaking destdir is prepended
|
(destdir ())^fn
|
||||||
* at the beginning of the target filename
|
|
||||||
*)
|
|
||||||
fun fn -> destdir^fn
|
|
||||||
with PropList.Not_set _ ->
|
with PropList.Not_set _ ->
|
||||||
fun fn -> fn
|
fn
|
||||||
in
|
in
|
||||||
|
|
||||||
let install_file ~ctxt ?(prepend_destdir=true) ?tgt_fn src_file envdir =
|
let install_file ~ctxt ?(prepend_destdir=true) ?tgt_fn src_file envdir =
|
||||||
|
|
@ -6471,7 +6462,7 @@ module InternalInstallPlugin = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 6474 "setup.ml"
|
# 6465 "setup.ml"
|
||||||
module OCamlbuildCommon = struct
|
module OCamlbuildCommon = struct
|
||||||
(* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
|
(* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
|
||||||
|
|
||||||
|
|
@ -6828,11 +6819,10 @@ module OCamlbuildDocPlugin = struct
|
||||||
run_ocamlbuild ~ctxt (index_html :: run.extra_args) argv;
|
run_ocamlbuild ~ctxt (index_html :: run.extra_args) argv;
|
||||||
List.iter
|
List.iter
|
||||||
(fun glb ->
|
(fun glb ->
|
||||||
BaseBuilt.register
|
match OASISFileUtil.glob ~ctxt (Filename.concat tgt_dir glb) with
|
||||||
~ctxt
|
| (_ :: _) as filenames ->
|
||||||
BaseBuilt.BDoc
|
BaseBuilt.register ~ctxt BaseBuilt.BDoc cs.cs_name [filenames]
|
||||||
cs.cs_name
|
| [] -> ())
|
||||||
[OASISFileUtil.glob ~ctxt (Filename.concat tgt_dir glb)])
|
|
||||||
["*.html"; "*.css"]
|
["*.html"; "*.css"]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6844,7 +6834,7 @@ module OCamlbuildDocPlugin = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 6847 "setup.ml"
|
# 6837 "setup.ml"
|
||||||
module CustomPlugin = struct
|
module CustomPlugin = struct
|
||||||
(* # 22 "src/plugins/custom/CustomPlugin.ml" *)
|
(* # 22 "src/plugins/custom/CustomPlugin.ml" *)
|
||||||
|
|
||||||
|
|
@ -6976,7 +6966,7 @@ module CustomPlugin = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 6979 "setup.ml"
|
# 6969 "setup.ml"
|
||||||
open OASISTypes;;
|
open OASISTypes;;
|
||||||
|
|
||||||
let setup_t =
|
let setup_t =
|
||||||
|
|
@ -7037,7 +7027,7 @@ let setup_t =
|
||||||
{
|
{
|
||||||
oasis_version = "0.4";
|
oasis_version = "0.4";
|
||||||
ocaml_version = None;
|
ocaml_version = None;
|
||||||
version = "0.10";
|
version = "0.11";
|
||||||
license =
|
license =
|
||||||
OASISLicense.DEP5License
|
OASISLicense.DEP5License
|
||||||
(OASISLicense.DEP5Unit
|
(OASISLicense.DEP5Unit
|
||||||
|
|
@ -8242,8 +8232,8 @@ let setup_t =
|
||||||
plugin_data = []
|
plugin_data = []
|
||||||
};
|
};
|
||||||
oasis_fn = Some "_oasis";
|
oasis_fn = Some "_oasis";
|
||||||
oasis_version = "0.4.8";
|
oasis_version = "0.4.10";
|
||||||
oasis_digest = Some "o\181u\130\246\134[37Z-Cy\216\208\151";
|
oasis_digest = Some "\027\154\201k\198D\228+r\225\172C\214\207\155\149";
|
||||||
oasis_exec = None;
|
oasis_exec = None;
|
||||||
oasis_setup_args = [];
|
oasis_setup_args = [];
|
||||||
setup_update = false
|
setup_update = false
|
||||||
|
|
@ -8251,7 +8241,7 @@ let setup_t =
|
||||||
|
|
||||||
let setup () = BaseSetup.setup setup_t;;
|
let setup () = BaseSetup.setup setup_t;;
|
||||||
|
|
||||||
# 8255 "setup.ml"
|
# 8245 "setup.ml"
|
||||||
let setup_t = BaseCompat.Compat_0_4.adapt_setup_t setup_t
|
let setup_t = BaseCompat.Compat_0_4.adapt_setup_t setup_t
|
||||||
open BaseCompat.Compat_0_4
|
open BaseCompat.Compat_0_4
|
||||||
(* OASIS_STOP *)
|
(* OASIS_STOP *)
|
||||||
|
|
|
||||||
8
src/META
8
src/META
|
|
@ -1,6 +1,6 @@
|
||||||
# OASIS_START
|
# OASIS_START
|
||||||
# DO NOT EDIT (digest: 47d925b722c4289a923085abbf97bba8)
|
# DO NOT EDIT (digest: 0035cfa1879430f352e735e279af06d0)
|
||||||
version = "0.10"
|
version = "0.11"
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
description = "Simple sequence (iterator) datatype and combinators"
|
||||||
requires = "bytes"
|
requires = "bytes"
|
||||||
archive(byte) = "sequence.cma"
|
archive(byte) = "sequence.cma"
|
||||||
|
|
@ -9,7 +9,7 @@ archive(native) = "sequence.cmxa"
|
||||||
archive(native, plugin) = "sequence.cmxs"
|
archive(native, plugin) = "sequence.cmxs"
|
||||||
exists_if = "sequence.cma"
|
exists_if = "sequence.cma"
|
||||||
package "invert" (
|
package "invert" (
|
||||||
version = "0.10"
|
version = "0.11"
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
description = "Simple sequence (iterator) datatype and combinators"
|
||||||
requires = "sequence delimcc"
|
requires = "sequence delimcc"
|
||||||
archive(byte) = "invert.cma"
|
archive(byte) = "invert.cma"
|
||||||
|
|
@ -20,7 +20,7 @@ package "invert" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "bigarray" (
|
package "bigarray" (
|
||||||
version = "0.10"
|
version = "0.11"
|
||||||
description = "Simple sequence (iterator) datatype and combinators"
|
description = "Simple sequence (iterator) datatype and combinators"
|
||||||
requires = "sequence bigarray"
|
requires = "sequence bigarray"
|
||||||
archive(byte) = "bigarray.cma"
|
archive(byte) = "bigarray.cma"
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,8 @@ let filter p seq k = seq (fun x -> if p x then k x)
|
||||||
|
|
||||||
let append s1 s2 k = s1 k; s2 k
|
let append s1 s2 k = s1 k; s2 k
|
||||||
|
|
||||||
|
let append_l l k = List.iter (fun sub -> sub k) l
|
||||||
|
|
||||||
let concat s k = s (fun s' -> s' k)
|
let concat s k = s (fun s' -> s' k)
|
||||||
|
|
||||||
(*$R
|
(*$R
|
||||||
|
|
@ -181,11 +183,32 @@ let flat_map f seq k = seq (fun x -> f x k)
|
||||||
let flat_map_l f seq k =
|
let flat_map_l f seq k =
|
||||||
seq (fun x -> List.iter k (f x))
|
seq (fun x -> List.iter k (f x))
|
||||||
|
|
||||||
|
let rec seq_list_map f l k = match l with
|
||||||
|
| [] -> k []
|
||||||
|
| x :: tail ->
|
||||||
|
f x (fun x' -> seq_list_map f tail (fun tail' -> k (x'::tail')))
|
||||||
|
|
||||||
|
let seq_list l = seq_list_map (fun x->x) l
|
||||||
|
|
||||||
|
(*$= & ~printer:Q.Print.(list @@ list int)
|
||||||
|
[[1;2];[1;3]] (seq_list [singleton 1; doubleton 2 3] |> to_list)
|
||||||
|
[] (seq_list [singleton 1; empty; doubleton 2 3] |> to_list)
|
||||||
|
[[1;2;4];[1;3;4]] (seq_list [singleton 1; doubleton 2 3; singleton 4] |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
let filter_map f seq k =
|
let filter_map f seq k =
|
||||||
seq (fun x -> match f x with
|
seq (fun x -> match f x with
|
||||||
| None -> ()
|
| None -> ()
|
||||||
| Some y -> k y
|
| Some y -> k y)
|
||||||
)
|
|
||||||
|
let filter_mapi f seq k =
|
||||||
|
let i = ref 0 in
|
||||||
|
seq (fun x ->
|
||||||
|
let j = !i in
|
||||||
|
incr i;
|
||||||
|
match f j x with
|
||||||
|
| None -> ()
|
||||||
|
| Some y -> k y)
|
||||||
|
|
||||||
let intersperse elem seq k =
|
let intersperse elem seq k =
|
||||||
let first = ref true in
|
let first = ref true in
|
||||||
|
|
@ -384,7 +407,10 @@ let group_succ_by ?(eq=fun x y -> x = y) seq k =
|
||||||
k l; (* yield group, and start another one *)
|
k l; (* yield group, and start another one *)
|
||||||
cur := [x]);
|
cur := [x]);
|
||||||
(* last list *)
|
(* last list *)
|
||||||
if !cur <> [] then k !cur
|
begin match !cur with
|
||||||
|
| [] -> ()
|
||||||
|
| (_::_) as l -> k l
|
||||||
|
end
|
||||||
|
|
||||||
(*$R
|
(*$R
|
||||||
[1;2;3;3;2;2;3;4]
|
[1;2;3;3;2;2;3;4]
|
||||||
|
|
@ -399,14 +425,16 @@ let group_by (type k) ?(hash=Hashtbl.hash) ?(eq=(=)) seq =
|
||||||
let hash = hash
|
let hash = hash
|
||||||
end) in
|
end) in
|
||||||
(* compute group table *)
|
(* compute group table *)
|
||||||
let tbl = Tbl.create 32 in
|
let tbl = lazy (
|
||||||
seq
|
let tbl = Tbl.create 32 in
|
||||||
(fun x ->
|
seq
|
||||||
let l = try Tbl.find tbl x with Not_found -> [] in
|
(fun x ->
|
||||||
Tbl.replace tbl x (x::l)
|
let l = try Tbl.find tbl x with Not_found -> [] in
|
||||||
);
|
Tbl.replace tbl x (x::l));
|
||||||
|
tbl
|
||||||
|
) in
|
||||||
fun yield ->
|
fun yield ->
|
||||||
Tbl.iter (fun _ l -> yield l) tbl
|
Tbl.iter (fun _ l -> yield l) (Lazy.force tbl)
|
||||||
|
|
||||||
(*$R
|
(*$R
|
||||||
[1;2;3;3;2;2;3;4]
|
[1;2;3;3;2;2;3;4]
|
||||||
|
|
@ -421,14 +449,16 @@ let count (type k) ?(hash=Hashtbl.hash) ?(eq=(=)) seq =
|
||||||
let hash = hash
|
let hash = hash
|
||||||
end) in
|
end) in
|
||||||
(* compute group table *)
|
(* compute group table *)
|
||||||
let tbl = Tbl.create 32 in
|
let tbl = lazy (
|
||||||
seq
|
let tbl = Tbl.create 32 in
|
||||||
(fun x ->
|
seq
|
||||||
let n = try Tbl.find tbl x with Not_found -> 0 in
|
(fun x ->
|
||||||
Tbl.replace tbl x (n+1)
|
let n = try Tbl.find tbl x with Not_found -> 0 in
|
||||||
);
|
Tbl.replace tbl x (n+1));
|
||||||
|
tbl
|
||||||
|
) in
|
||||||
fun yield ->
|
fun yield ->
|
||||||
Tbl.iter (fun x n -> yield (x,n)) tbl
|
Tbl.iter (fun x n -> yield (x,n)) (Lazy.force tbl)
|
||||||
|
|
||||||
(*$R
|
(*$R
|
||||||
[1;2;3;3;2;2;3;4]
|
[1;2;3;3;2;2;3;4]
|
||||||
|
|
@ -714,6 +744,32 @@ let min_exn ?lt seq = match min ?lt seq with
|
||||||
0 (0 -- 100 |> min_exn ?lt:None)
|
0 (0 -- 100 |> min_exn ?lt:None)
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
let sum seq =
|
||||||
|
let n = ref 0 in
|
||||||
|
seq (fun x -> n := !n + x);
|
||||||
|
!n
|
||||||
|
|
||||||
|
(*$T
|
||||||
|
(of_list [1;2;3] |> sum) = 6
|
||||||
|
*)
|
||||||
|
|
||||||
|
(* https://en.wikipedia.org/wiki/Kahan_summation_algorithm *)
|
||||||
|
let sumf seq : float =
|
||||||
|
let sum = ref 0. in
|
||||||
|
let c = ref 0. in (* error compensation *)
|
||||||
|
seq
|
||||||
|
(fun x ->
|
||||||
|
let y = x -. !c in
|
||||||
|
let t = !sum +. y in
|
||||||
|
c := (t -. !sum) -. y;
|
||||||
|
sum := t);
|
||||||
|
!sum
|
||||||
|
|
||||||
|
(*$R
|
||||||
|
let seq = of_list [10000.0; 3.14159; 2.71828] in
|
||||||
|
assert_equal ~printer:string_of_float 10005.85987 (sumf seq)
|
||||||
|
*)
|
||||||
|
|
||||||
exception ExitHead
|
exception ExitHead
|
||||||
|
|
||||||
let head seq =
|
let head seq =
|
||||||
|
|
@ -932,6 +988,10 @@ let of_list l k = List.iter k l
|
||||||
let on_list f l =
|
let on_list f l =
|
||||||
to_list (f (of_list l))
|
to_list (f (of_list l))
|
||||||
|
|
||||||
|
let pair_with_idx seq k =
|
||||||
|
let r = ref 0 in
|
||||||
|
seq (fun x -> let n = !r in incr r; k (n,x))
|
||||||
|
|
||||||
let to_opt = head
|
let to_opt = head
|
||||||
|
|
||||||
let of_opt o k = match o with
|
let of_opt o k = match o with
|
||||||
|
|
@ -1047,7 +1107,7 @@ let to_buffer seq buf =
|
||||||
(*$R
|
(*$R
|
||||||
let b = Buffer.create 4 in
|
let b = Buffer.create 4 in
|
||||||
"hello world"
|
"hello world"
|
||||||
|> of_str |> rev |> map Char.uppercase
|
|> of_str |> rev |> map Char.uppercase_ascii
|
||||||
|> (fun seq -> to_buffer seq b);
|
|> (fun seq -> to_buffer seq b);
|
||||||
OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
|
OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
|
||||||
*)
|
*)
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,11 @@ val append : 'a t -> 'a t -> 'a t
|
||||||
(** Append two sequences. Iterating on the result is like iterating
|
(** Append two sequences. Iterating on the result is like iterating
|
||||||
on the first, then on the second. *)
|
on the first, then on the second. *)
|
||||||
|
|
||||||
|
val append_l : 'a t list -> 'a t
|
||||||
|
(** Append sequences. Iterating on the result is like iterating
|
||||||
|
on the each sequence of the list in order.
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val concat : 'a t t -> 'a t
|
val concat : 'a t t -> 'a t
|
||||||
(** Concatenate a sequence of sequences into one sequence. *)
|
(** Concatenate a sequence of sequences into one sequence. *)
|
||||||
|
|
||||||
|
|
@ -200,11 +205,25 @@ val flat_map_l : ('a -> 'b list) -> 'a t -> 'b t
|
||||||
(** Convenience function combining {!flat_map} and {!of_list}
|
(** Convenience function combining {!flat_map} and {!of_list}
|
||||||
@since 0.8 *)
|
@since 0.8 *)
|
||||||
|
|
||||||
|
val seq_list : 'a t list -> 'a list t
|
||||||
|
(** [seq_list l] returns all the ways to pick one element in each sub-sequence
|
||||||
|
in [l]. Assumes the sub-sequences can be iterated on several times.
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
|
val seq_list_map : ('a -> 'b t) -> 'a list -> 'b list t
|
||||||
|
(** [seq_list_map f l] maps [f] over every element of [l],
|
||||||
|
then calls {!seq_list}
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
|
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
|
||||||
(** Map and only keep non-[None] elements
|
(** Map and only keep non-[None] elements
|
||||||
Formerly [fmap]
|
Formerly [fmap]
|
||||||
@since 0.5 *)
|
@since 0.5 *)
|
||||||
|
|
||||||
|
val filter_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b t
|
||||||
|
(** Map with indices, and only keep non-[None] elements
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val intersperse : 'a -> 'a t -> 'a t
|
val intersperse : 'a -> 'a t -> 'a t
|
||||||
(** Insert the single element between every element of the sequence *)
|
(** Insert the single element between every element of the sequence *)
|
||||||
|
|
||||||
|
|
@ -242,7 +261,7 @@ val sorted : ?cmp:('a -> 'a -> int) -> 'a t -> bool
|
||||||
@since 0.9 *)
|
@since 0.9 *)
|
||||||
|
|
||||||
val group_succ_by : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
|
val group_succ_by : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
|
||||||
(** Group equal consecutive elements.
|
(** Group equal consecutive elements. Linear time.
|
||||||
Formerly synonym to [group].
|
Formerly synonym to [group].
|
||||||
@since 0.6 *)
|
@since 0.6 *)
|
||||||
|
|
||||||
|
|
@ -250,12 +269,14 @@ val group_by : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) ->
|
||||||
'a t -> 'a list t
|
'a t -> 'a list t
|
||||||
(** Group equal elements, disregarding their order of appearance.
|
(** Group equal elements, disregarding their order of appearance.
|
||||||
The result sequence is traversable as many times as required.
|
The result sequence is traversable as many times as required.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.6 *)
|
@since 0.6 *)
|
||||||
|
|
||||||
val count : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) ->
|
val count : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) ->
|
||||||
'a t -> ('a * int) t
|
'a t -> ('a * int) t
|
||||||
(** Map each distinct element to its number of occurrences in the whole seq.
|
(** Map each distinct element to its number of occurrences in the whole seq.
|
||||||
Similar to [group_by seq |> map (fun l->List.hd l, List.length l)]
|
Similar to [group_by seq |> map (fun l->List.hd l, List.length l)]
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.10 *)
|
@since 0.10 *)
|
||||||
|
|
||||||
val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t
|
val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t
|
||||||
|
|
@ -300,6 +321,7 @@ val join_by : ?eq:'key equal -> ?hash:'key hash ->
|
||||||
values [(x,y)] from [(a,b)] with the same [key]
|
values [(x,y)] from [(a,b)] with the same [key]
|
||||||
using [merge]. If [merge] returns [None], the combination
|
using [merge]. If [merge] returns [None], the combination
|
||||||
of values is discarded.
|
of values is discarded.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.10 *)
|
@since 0.10 *)
|
||||||
|
|
||||||
val join_all_by : ?eq:'key equal -> ?hash:'key hash ->
|
val join_all_by : ?eq:'key equal -> ?hash:'key hash ->
|
||||||
|
|
@ -329,6 +351,7 @@ val group_join_by : ?eq:'a equal -> ?hash:'a hash ->
|
||||||
sequence such that [eq x (key y)]. Elements of the first
|
sequence such that [eq x (key y)]. Elements of the first
|
||||||
sequences without corresponding values in the second one
|
sequences without corresponding values in the second one
|
||||||
are mapped to [[]]
|
are mapped to [[]]
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.10 *)
|
@since 0.10 *)
|
||||||
|
|
||||||
val inter :
|
val inter :
|
||||||
|
|
@ -336,6 +359,7 @@ val inter :
|
||||||
'a t -> 'a t -> 'a t
|
'a t -> 'a t -> 'a t
|
||||||
(** Intersection of two collections. Each element will occur at most once
|
(** Intersection of two collections. Each element will occur at most once
|
||||||
in the result. Eager.
|
in the result. Eager.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.10 *)
|
@since 0.10 *)
|
||||||
|
|
||||||
(*$=
|
(*$=
|
||||||
|
|
@ -348,6 +372,7 @@ val union :
|
||||||
'a t -> 'a t -> 'a t
|
'a t -> 'a t -> 'a t
|
||||||
(** Union of two collections. Each element will occur at most once
|
(** Union of two collections. Each element will occur at most once
|
||||||
in the result. Eager.
|
in the result. Eager.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.10 *)
|
@since 0.10 *)
|
||||||
|
|
||||||
(*$=
|
(*$=
|
||||||
|
|
@ -368,6 +393,7 @@ val subset :
|
||||||
?eq:'a equal -> ?hash:'a hash ->
|
?eq:'a equal -> ?hash:'a hash ->
|
||||||
'a t -> 'a t -> bool
|
'a t -> 'a t -> bool
|
||||||
(** [subset a b] returns [true] if all elements of [a] belong to [b]. Eager.
|
(** [subset a b] returns [true] if all elements of [a] belong to [b]. Eager.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.10 *)
|
@since 0.10 *)
|
||||||
|
|
||||||
(*$T
|
(*$T
|
||||||
|
|
@ -402,6 +428,14 @@ val min_exn : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
|
||||||
@raise Not_found if the sequence is empty
|
@raise Not_found if the sequence is empty
|
||||||
@since 0.10 *)
|
@since 0.10 *)
|
||||||
|
|
||||||
|
val sum : int t -> int
|
||||||
|
(** Sum of elements
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
|
val sumf : float t -> float
|
||||||
|
(** Sum of elements, using Kahan summation
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val head : 'a t -> 'a option
|
val head : 'a t -> 'a option
|
||||||
(** First element, if any, otherwise [None]
|
(** First element, if any, otherwise [None]
|
||||||
@since 0.5.1 *)
|
@since 0.5.1 *)
|
||||||
|
|
@ -477,6 +511,10 @@ val on_list : ('a t -> 'b t) -> 'a list -> 'b list
|
||||||
@since 0.5.2
|
@since 0.5.2
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
val pair_with_idx : 'a t -> (int * 'a) t
|
||||||
|
(** Similar to {!zip_i} but returns a normal sequence of tuples
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val to_opt : 'a t -> 'a option
|
val to_opt : 'a t -> 'a option
|
||||||
(** Alias to {!head}
|
(** Alias to {!head}
|
||||||
@since 0.5.1 *)
|
@since 0.5.1 *)
|
||||||
|
|
|
||||||
1
src/SequenceLabels.ml
Normal file
1
src/SequenceLabels.ml
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
include Sequence
|
||||||
|
|
@ -17,6 +17,9 @@ type +'a sequence = 'a t
|
||||||
type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
|
type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
|
||||||
(** Sequence of pairs of values of type ['a] and ['b]. *)
|
(** Sequence of pairs of values of type ['a] and ['b]. *)
|
||||||
|
|
||||||
|
type 'a equal = 'a -> 'a -> bool
|
||||||
|
type 'a hash = 'a -> int
|
||||||
|
|
||||||
(** {2 Build a sequence} *)
|
(** {2 Build a sequence} *)
|
||||||
|
|
||||||
val from_iter : (('a -> unit) -> unit) -> 'a t
|
val from_iter : (('a -> unit) -> unit) -> 'a t
|
||||||
|
|
@ -115,15 +118,25 @@ val exists : f:('a -> bool) -> 'a t -> bool
|
||||||
|
|
||||||
val mem : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> bool
|
val mem : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> bool
|
||||||
(** Is the value a member of the sequence?
|
(** Is the value a member of the sequence?
|
||||||
@param eq the equality predicate to use (default [(=)]) *)
|
@param eq the equality predicate to use (default [(=)])
|
||||||
|
@since 0.5 *)
|
||||||
|
|
||||||
val find : f:('a -> 'b option) -> 'a t -> 'b option
|
val find : ('a -> 'b option) -> 'a t -> 'b option
|
||||||
(** Find the first element on which the function doesn't return [None] *)
|
(** Find the first element on which the function doesn't return [None]
|
||||||
|
@since 0.5 *)
|
||||||
|
|
||||||
|
val find_map : f:('a -> 'b option) -> 'a t -> 'b option
|
||||||
|
(** Alias to {!find}
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
val findi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
|
val findi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
|
||||||
(** Indexed version of {!find}
|
(** Indexed version of {!find}
|
||||||
@since 0.9 *)
|
@since 0.9 *)
|
||||||
|
|
||||||
|
val find_mapi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
|
||||||
|
(** Alias to {!findi}
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
val find_pred : f:('a -> bool) -> 'a t -> 'a option
|
val find_pred : f:('a -> bool) -> 'a t -> 'a option
|
||||||
(** [find_pred p l] finds the first element of [l] that satisfies [p],
|
(** [find_pred p l] finds the first element of [l] that satisfies [p],
|
||||||
or returns [None] if no element satisfies [p]
|
or returns [None] if no element satisfies [p]
|
||||||
|
|
@ -149,6 +162,11 @@ val append : 'a t -> 'a t -> 'a t
|
||||||
(** Append two sequences. Iterating on the result is like iterating
|
(** Append two sequences. Iterating on the result is like iterating
|
||||||
on the first, then on the second. *)
|
on the first, then on the second. *)
|
||||||
|
|
||||||
|
val append_l : 'a t list -> 'a t
|
||||||
|
(** Append sequences. Iterating on the result is like iterating
|
||||||
|
on the each sequence of the list in order.
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val concat : 'a t t -> 'a t
|
val concat : 'a t t -> 'a t
|
||||||
(** Concatenate a sequence of sequences into one sequence. *)
|
(** Concatenate a sequence of sequences into one sequence. *)
|
||||||
|
|
||||||
|
|
@ -165,6 +183,20 @@ val flat_map_l : f:('a -> 'b list) -> 'a t -> 'b t
|
||||||
val filter_map : f:('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 *)
|
(** Alias to {!fmap} with a more explicit name *)
|
||||||
|
|
||||||
|
val filter_mapi : f:(int -> 'a -> 'b option) -> 'a t -> 'b t
|
||||||
|
(** Map with indices, and only keep non-[None] elements
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
|
val seq_list : 'a t list -> 'a list t
|
||||||
|
(** [seq_list l] returns all the ways to pick one element in each sub-sequence
|
||||||
|
in [l]. Assumes the sub-sequences can be iterated on several times.
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
|
val seq_list_map : f:('a -> 'b t) -> 'a list -> 'b list t
|
||||||
|
(** [seq_list_map f l] maps [f] over every element of [l],
|
||||||
|
then calls {!seq_list}
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val intersperse : x:'a -> 'a t -> 'a t
|
val intersperse : x:'a -> 'a t -> 'a t
|
||||||
(** Insert the single element between every element of the sequence *)
|
(** Insert the single element between every element of the sequence *)
|
||||||
|
|
||||||
|
|
@ -210,6 +242,7 @@ val group_by : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) ->
|
||||||
'a t -> 'a list t
|
'a t -> 'a list t
|
||||||
(** Group equal elements, disregarding their order of appearance.
|
(** Group equal elements, disregarding their order of appearance.
|
||||||
The result sequence is traversable as many times as required.
|
The result sequence is traversable as many times as required.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
@since 0.6 *)
|
@since 0.6 *)
|
||||||
|
|
||||||
val count : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) ->
|
val count : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) ->
|
||||||
|
|
@ -239,7 +272,8 @@ val diagonal : 'a t -> ('a * 'a) t
|
||||||
@since 0.9 *)
|
@since 0.9 *)
|
||||||
|
|
||||||
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
||||||
(** Binary version of {!product}. Same requirements. *)
|
(** Binary version of {!product}. Same requirements.
|
||||||
|
@since 0.5 *)
|
||||||
|
|
||||||
val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
|
val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
|
||||||
(** [join ~join_row a b] combines every element of [a] with every
|
(** [join ~join_row a b] combines every element of [a] with every
|
||||||
|
|
@ -247,6 +281,98 @@ val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
|
||||||
the two elements do not combine. Assume that [b] allows for multiple
|
the two elements do not combine. Assume that [b] allows for multiple
|
||||||
iterations. *)
|
iterations. *)
|
||||||
|
|
||||||
|
val join_by : ?eq:'key equal -> ?hash:'key hash ->
|
||||||
|
('a -> 'key) -> ('b -> 'key) ->
|
||||||
|
merge:('key -> 'a -> 'b -> 'c option) ->
|
||||||
|
'a t ->
|
||||||
|
'b t ->
|
||||||
|
'c t
|
||||||
|
(** [join key1 key2 ~merge] is a binary operation
|
||||||
|
that takes two sequences [a] and [b], projects their
|
||||||
|
elements resp. with [key1] and [key2], and combine
|
||||||
|
values [(x,y)] from [(a,b)] with the same [key]
|
||||||
|
using [merge]. If [merge] returns [None], the combination
|
||||||
|
of values is discarded.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
val join_all_by : ?eq:'key equal -> ?hash:'key hash ->
|
||||||
|
('a -> 'key) -> ('b -> 'key) ->
|
||||||
|
merge:('key -> 'a list -> 'b list -> 'c option) ->
|
||||||
|
'a t ->
|
||||||
|
'b t ->
|
||||||
|
'c t
|
||||||
|
(** [join_all_by key1 key2 ~merge] is a binary operation
|
||||||
|
that takes two sequences [a] and [b], projects their
|
||||||
|
elements resp. with [key1] and [key2], and, for each key [k]
|
||||||
|
occurring in at least one of them:
|
||||||
|
- compute the list [l1] of elements of [a] that map to [k]
|
||||||
|
- compute the list [l2] of elements of [b] that map to [k]
|
||||||
|
- call [merge k l1 l2]. If [merge] returns [None], the combination
|
||||||
|
of values is discarded, otherwise it returns [Some c]
|
||||||
|
and [c] is inserted in the result.
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
val group_join_by : ?eq:'a equal -> ?hash:'a hash ->
|
||||||
|
('b -> 'a) ->
|
||||||
|
'a t ->
|
||||||
|
'b t ->
|
||||||
|
('a * 'b list) t
|
||||||
|
(** [group_join_by key2] associates to every element [x] of
|
||||||
|
the first sequence, all the elements [y] of the second
|
||||||
|
sequence such that [eq x (key y)]. Elements of the first
|
||||||
|
sequences without corresponding values in the second one
|
||||||
|
are mapped to [[]]
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
val inter :
|
||||||
|
?eq:'a equal -> ?hash:'a hash ->
|
||||||
|
'a t -> 'a t -> 'a t
|
||||||
|
(** Intersection of two collections. Each element will occur at most once
|
||||||
|
in the result. Eager.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
[2;4;5;6] (inter (1--6) (cons 2 (4--10)) |> sort |> to_list)
|
||||||
|
[] (inter (0--5) (6--10) |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
val union :
|
||||||
|
?eq:'a equal -> ?hash:'a hash ->
|
||||||
|
'a t -> 'a t -> 'a t
|
||||||
|
(** Union of two collections. Each element will occur at most once
|
||||||
|
in the result. Eager.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
[2;4;5;6] (union (4--6) (cons 2 (4--5)) |> sort |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
val diff :
|
||||||
|
?eq:'a equal -> ?hash:'a hash ->
|
||||||
|
'a t -> 'a t -> 'a t
|
||||||
|
(** Set difference. Eager.
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
[1;2;8;9;10] (diff (1--10) (3--7) |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
val subset :
|
||||||
|
?eq:'a equal -> ?hash:'a hash ->
|
||||||
|
'a t -> 'a t -> bool
|
||||||
|
(** [subset a b] returns [true] if all elements of [a] belong to [b]. Eager.
|
||||||
|
precondition: for any [x] and [y], if [eq x y] then [hash x=hash y] must hold.
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
(*$T
|
||||||
|
subset (2 -- 4) (1 -- 4)
|
||||||
|
not (subset (1 -- 4) (2 -- 10))
|
||||||
|
*)
|
||||||
|
|
||||||
val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
|
val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
|
||||||
(** [unfoldr f b] will apply [f] to [b]. If it
|
(** [unfoldr f b] will apply [f] to [b]. If it
|
||||||
yields [Some (x,b')] then [x] is returned
|
yields [Some (x,b')] then [x] is returned
|
||||||
|
|
@ -260,16 +386,36 @@ val max : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option
|
||||||
@return None if the sequence is empty, Some [m] where [m] is the maximal
|
@return None if the sequence is empty, Some [m] where [m] is the maximal
|
||||||
element otherwise *)
|
element otherwise *)
|
||||||
|
|
||||||
|
val max_exn : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
|
||||||
|
(** Unsafe version of {!max}
|
||||||
|
@raise Not_found if the sequence is empty
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option
|
val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a option
|
||||||
(** Min element of the sequence, using the given comparison function.
|
(** Min element of the sequence, using the given comparison function.
|
||||||
see {!max} for more details. *)
|
see {!max} for more details. *)
|
||||||
|
|
||||||
|
val min_exn : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
|
||||||
|
(** Unsafe version of {!min}
|
||||||
|
@raise Not_found if the sequence is empty
|
||||||
|
@since 0.10 *)
|
||||||
|
|
||||||
|
val sum : int t -> int
|
||||||
|
(** Sum of elements
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
|
val sumf : float t -> float
|
||||||
|
(** Sum of elements, using Kahan summation
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val head : 'a t -> 'a option
|
val head : 'a t -> 'a option
|
||||||
(** First element, if any, otherwise [None] *)
|
(** First element, if any, otherwise [None]
|
||||||
|
@since 0.5.1 *)
|
||||||
|
|
||||||
val head_exn : 'a t -> 'a
|
val head_exn : 'a t -> 'a
|
||||||
(** First element, if any, fails
|
(** First element, if any, fails
|
||||||
@raise Invalid_argument if the sequence is empty *)
|
@raise Invalid_argument if the sequence is empty
|
||||||
|
@since 0.5.1 *)
|
||||||
|
|
||||||
val take : int -> 'a t -> 'a t
|
val take : int -> 'a t -> 'a t
|
||||||
(** Take at most [n] elements from the sequence. Works on infinite
|
(** Take at most [n] elements from the sequence. Works on infinite
|
||||||
|
|
@ -282,7 +428,8 @@ val take_while : f:('a -> bool) -> 'a t -> 'a t
|
||||||
|
|
||||||
val fold_while : f:('a -> 'b -> 'a * [`Stop | `Continue]) -> init:'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
|
(** Folds over elements of the sequence, stopping early if the accumulator
|
||||||
returns [('a, `Stop)] *)
|
returns [('a, `Stop)]
|
||||||
|
@since 0.5.5 *)
|
||||||
|
|
||||||
val drop : int -> 'a t -> 'a t
|
val drop : int -> 'a t -> 'a t
|
||||||
(** Drop the [n] first elements of the sequence. Lazy. *)
|
(** Drop the [n] first elements of the sequence. Lazy. *)
|
||||||
|
|
@ -332,10 +479,17 @@ val to_rev_list : 'a t -> 'a list
|
||||||
val of_list : 'a list -> 'a t
|
val of_list : 'a list -> 'a t
|
||||||
|
|
||||||
val on_list : ('a t -> 'b t) -> 'a list -> 'b list
|
val on_list : ('a t -> 'b t) -> 'a list -> 'b list
|
||||||
(** [on_list f l] is equivalent to [to_list @@ f @@ of_list l]. *)
|
(** [on_list f l] is equivalent to [to_list @@ f @@ of_list l].
|
||||||
|
@since 0.5.2
|
||||||
|
*)
|
||||||
|
|
||||||
|
val pair_with_idx : 'a t -> (int * 'a) t
|
||||||
|
(** Similar to {!zip_i} but returns a normal sequence of tuples
|
||||||
|
@since 0.11 *)
|
||||||
|
|
||||||
val to_opt : 'a t -> 'a option
|
val to_opt : 'a t -> 'a option
|
||||||
(** Alias to {!head} *)
|
(** Alias to {!head}
|
||||||
|
@since 0.5.1 *)
|
||||||
|
|
||||||
val to_array : 'a t -> 'a array
|
val to_array : 'a t -> 'a array
|
||||||
(** Convert to an array. Currently not very efficient because
|
(** Convert to an array. Currently not very efficient because
|
||||||
|
|
@ -353,7 +507,8 @@ val array_slice : 'a array -> int -> int -> 'a t
|
||||||
from [i] to [j] *)
|
from [i] to [j] *)
|
||||||
|
|
||||||
val of_opt : 'a option -> 'a t
|
val of_opt : 'a option -> 'a t
|
||||||
(** Iterate on 0 or 1 values. *)
|
(** Iterate on 0 or 1 values.
|
||||||
|
@since 0.5.1 *)
|
||||||
|
|
||||||
val of_stream : 'a Stream.t -> 'a t
|
val of_stream : 'a Stream.t -> 'a t
|
||||||
(** Sequence of elements of a stream (usable only once) *)
|
(** Sequence of elements of a stream (usable only once) *)
|
||||||
|
|
@ -401,7 +556,8 @@ val to_str : char t -> string
|
||||||
|
|
||||||
val concat_str : string t -> string
|
val concat_str : string t -> string
|
||||||
(** Concatenate strings together, eagerly.
|
(** Concatenate strings together, eagerly.
|
||||||
Also see {!intersperse} to add a separator. *)
|
Also see {!intersperse} to add a separator.
|
||||||
|
@since 0.5 *)
|
||||||
|
|
||||||
exception OneShotSequence
|
exception OneShotSequence
|
||||||
(** Raised when the user tries to iterate several times on
|
(** Raised when the user tries to iterate several times on
|
||||||
|
|
@ -547,16 +703,20 @@ module Infix : sig
|
||||||
It will therefore be empty if [a < b]. *)
|
It will therefore be empty if [a < b]. *)
|
||||||
|
|
||||||
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
|
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
|
||||||
(** Monadic bind (infix version of {!flat_map} *)
|
(** Monadic bind (infix version of {!flat_map}
|
||||||
|
@since 0.5 *)
|
||||||
|
|
||||||
val (>|=) : 'a t -> ('a -> 'b) -> 'b t
|
val (>|=) : 'a t -> ('a -> 'b) -> 'b t
|
||||||
(** Infix version of {!map} *)
|
(** Infix version of {!map}
|
||||||
|
@since 0.5 *)
|
||||||
|
|
||||||
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
|
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
|
||||||
(** Applicative operator (product+application) *)
|
(** Applicative operator (product+application)
|
||||||
|
@since 0.5 *)
|
||||||
|
|
||||||
val (<+>) : 'a t -> 'a t -> 'a t
|
val (<+>) : 'a t -> 'a t -> 'a t
|
||||||
(** Concatenation of sequences *)
|
(** Concatenation of sequences
|
||||||
|
@since 0.5 *)
|
||||||
end
|
end
|
||||||
|
|
||||||
include module type of Infix
|
include module type of Infix
|
||||||
|
|
@ -600,7 +760,7 @@ val to_string : ?sep:string -> ('a -> string) -> 'a t -> string
|
||||||
Sequence.IO.lines "a" |> Sequence.to_list
|
Sequence.IO.lines "a" |> Sequence.to_list
|
||||||
]}
|
]}
|
||||||
|
|
||||||
*)
|
@since 0.5.1 *)
|
||||||
|
|
||||||
module IO : sig
|
module IO : sig
|
||||||
val lines_of : ?mode:int -> ?flags:open_flag list ->
|
val lines_of : ?mode:int -> ?flags:open_flag list ->
|
||||||
|
|
@ -630,7 +790,7 @@ module IO : sig
|
||||||
|
|
||||||
val write_bytes_to : ?mode:int -> ?flags:open_flag list ->
|
val write_bytes_to : ?mode:int -> ?flags:open_flag list ->
|
||||||
string -> Bytes.t t -> unit
|
string -> Bytes.t t -> unit
|
||||||
(** *)
|
(** @since 0.5.4 *)
|
||||||
|
|
||||||
val write_lines : ?mode:int -> ?flags:open_flag list ->
|
val write_lines : ?mode:int -> ?flags:open_flag list ->
|
||||||
string -> string t -> unit
|
string -> string t -> unit
|
||||||
|
|
@ -638,4 +798,5 @@ module IO : sig
|
||||||
|
|
||||||
val write_bytes_lines : ?mode:int -> ?flags:open_flag list ->
|
val write_bytes_lines : ?mode:int -> ?flags:open_flag list ->
|
||||||
string -> Bytes.t t -> unit
|
string -> Bytes.t t -> unit
|
||||||
|
(** @since 0.5.4 *)
|
||||||
end
|
end
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Sequence.ml
|
|
||||||
Loading…
Add table
Reference in a new issue