Merge branch 'master' into stable; oasis setup; 0.8

This commit is contained in:
Simon Cruanes 2016-07-26 10:16:07 +02:00
commit 666b7b6442
28 changed files with 1749 additions and 363 deletions

View file

@ -1,9 +1,9 @@
#directory "_build";;
#directory "_build/src";;
#load "sequence.cma";;
open Sequence.Infix;;
#directory "_build/bigarray/";;
#directory "_build/src/bigarray/";;
#load "bigarray.cma";;
(* vim:syntax=ocaml *)

View file

@ -40,8 +40,24 @@ configure:
# OASIS_STOP
run-tests:
./run_tests.native
QTEST_PREAMBLE=''
DONTTEST=src/sequenceLabels.ml
QTESTABLE=$(filter-out $(DONTTEST), \
$(wildcard src/*.ml) \
$(wildcard src/*.mli) \
)
qtest-clean:
@rm -rf qtest/
qtest-gen:
@mkdir -p qtest
@if which qtest > /dev/null ; then \
qtest extract --preamble $(QTEST_PREAMBLE) \
-o qtest/run_qtest.ml \
$(QTESTABLE) 2> /dev/null ; \
else touch qtest/run_qtest.ml ; \
fi
examples:
ocamlbuild examples/test_sexpr.native
@ -59,7 +75,7 @@ push_stable: all
VERSION=$(shell awk '/^Version:/ {print $$2}' _oasis)
SOURCE=*.ml *.mli invert/*.ml invert/*.mli bigarray/*.ml bigarray/*.mli
SOURCE=$(addprefix src/, *.ml *.mli invert/*.ml invert/*.mli bigarray/*.ml bigarray/*.mli)
update_next_tag:
@echo "update version to $(VERSION)..."

View file

@ -15,7 +15,14 @@ of a `Hashtbl.t`, without creating a list.
Documentation
=============
See [the online API](http://cedeela.fr/~simon/software/sequence/Sequence.html).
There is only one type, `'a Sequence.t`, and lots of functions built around
this type.
To get an overview of sequence, its origins and why it was created,
you can start with [the slides of a talk](http://cedeela.fr/~simon/talks/sequence.pdf)
I (c-cube) made at some OCaml meeting.
See [the online API](http://cedeela.fr/~simon/software/sequence/Sequence.html)
for more details on the set of available functions.
Build
=====

27
_oasis
View file

@ -1,6 +1,6 @@
OASISFormat: 0.4
Name: sequence
Version: 0.7
Version: 0.8
Homepage: https://github.com/c-cube/sequence
Authors: Simon Cruanes
License: BSD-2-clause
@ -28,12 +28,12 @@ Flag bigarray
Default: true
Library "sequence"
Path: .
Path: src/
Modules: Sequence, SequenceLabels
BuildDepends: bytes
Library "invert"
Path: invert
Path: src/invert
Build$: flag(invert)
Install$: flag(invert)
Modules: SequenceInvert
@ -42,7 +42,7 @@ Library "invert"
BuildDepends: sequence,delimcc
Library "bigarray"
Path: bigarray
Path: src/bigarray
Build$: flag(bigarray)
Install$: flag(bigarray)
Modules: SequenceBigarray
@ -58,19 +58,20 @@ Document sequence
XOCamlbuildPath: .
XOCamlbuildLibraries: sequence
Test all
Type: custom (0.4)
Command: make run-tests
TestTools: run_tests
Run$: flag(tests)
PreBuildCommand: make qtest-gen
Executable run_tests
Path: tests/
Executable run_qtest
Path: qtest/
Install: false
CompiledObject: native
MainIs: run_tests.ml
MainIs: run_qtest.ml
Build$: flag(tests)
BuildDepends: sequence,oUnit
BuildDepends: sequence, qcheck
Test all
Command: ./run_qtest.native
TestTools: run_qtest
Run$: flag(tests)
Executable benchs
Path: bench

39
_tags
View file

@ -1,5 +1,5 @@
# OASIS_START
# DO NOT EDIT (digest: 29e0c9fc65daf16caa16466d6ff32bac)
# DO NOT EDIT (digest: 5495b2a66019398a5b6c2172a2c3ba42)
# Ignore VCS directories, you can use the same kind of rule outside
# OASIS_START/STOP if you want to exclude directories that contains
# useless stuff for the build process
@ -15,25 +15,25 @@ true: annot, bin_annot
"_darcs": -traverse
"_darcs": not_hygienic
# Library sequence
"sequence.cmxs": use_sequence
<*.ml{,i,y}>: pkg_bytes
"src/sequence.cmxs": use_sequence
<src/*.ml{,i,y}>: pkg_bytes
# Library invert
"invert/invert.cmxs": use_invert
<invert/*.ml{,i,y}>: pkg_bytes
<invert/*.ml{,i,y}>: pkg_delimcc
<invert/*.ml{,i,y}>: use_sequence
"src/invert/invert.cmxs": use_invert
<src/invert/*.ml{,i,y}>: pkg_bytes
<src/invert/*.ml{,i,y}>: pkg_delimcc
<src/invert/*.ml{,i,y}>: use_sequence
# Library bigarray
"bigarray/bigarray.cmxs": use_bigarray
<bigarray/*.ml{,i,y}>: pkg_bigarray
<bigarray/*.ml{,i,y}>: pkg_bytes
<bigarray/*.ml{,i,y}>: use_sequence
# Executable run_tests
"tests/run_tests.native": pkg_bytes
"tests/run_tests.native": pkg_oUnit
"tests/run_tests.native": use_sequence
<tests/*.ml{,i,y}>: pkg_bytes
<tests/*.ml{,i,y}>: pkg_oUnit
<tests/*.ml{,i,y}>: use_sequence
"src/bigarray/bigarray.cmxs": use_bigarray
<src/bigarray/*.ml{,i,y}>: pkg_bigarray
<src/bigarray/*.ml{,i,y}>: pkg_bytes
<src/bigarray/*.ml{,i,y}>: use_sequence
# Executable run_qtest
"qtest/run_qtest.native": pkg_bytes
"qtest/run_qtest.native": pkg_qcheck
"qtest/run_qtest.native": use_sequence
<qtest/*.ml{,i,y}>: pkg_bytes
<qtest/*.ml{,i,y}>: pkg_qcheck
<qtest/*.ml{,i,y}>: use_sequence
# Executable benchs
"bench/benchs.native": pkg_benchmark
"bench/benchs.native": pkg_bytes
@ -53,4 +53,5 @@ true: annot, bin_annot
true: bin_annot
<**/*.ml>: warn_A, warn(-4)
true: mark_tag_used
<sequenceLabels.cm*>: nolabels
<**/*.cmx>: optimize(3)
<src/sequenceLabels.cm*>: nolabels

View file

@ -1,5 +1,5 @@
(* OASIS_START *)
(* DO NOT EDIT (digest: 2ea21bad023bcdcb9626e204d039d0d2) *)
(* DO NOT EDIT (digest: 8cefc2cf375bc79d721299976e7d0715) *)
module OASISGettext = struct
(* # 22 "src/oasis/OASISGettext.ml" *)
@ -29,6 +29,166 @@ module OASISGettext = struct
end
module OASISString = struct
(* # 22 "src/oasis/OASISString.ml" *)
(** Various string utilities.
Mostly inspired by extlib and batteries ExtString and BatString libraries.
@author Sylvain Le Gall
*)
let nsplitf str f =
if str = "" then
[]
else
let buf = Buffer.create 13 in
let lst = ref [] in
let push () =
lst := Buffer.contents buf :: !lst;
Buffer.clear buf
in
let str_len = String.length str in
for i = 0 to str_len - 1 do
if f str.[i] then
push ()
else
Buffer.add_char buf str.[i]
done;
push ();
List.rev !lst
(** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
separator.
*)
let nsplit str c =
nsplitf str ((=) c)
let find ~what ?(offset=0) str =
let what_idx = ref 0 in
let str_idx = ref offset in
while !str_idx < String.length str &&
!what_idx < String.length what do
if str.[!str_idx] = what.[!what_idx] then
incr what_idx
else
what_idx := 0;
incr str_idx
done;
if !what_idx <> String.length what then
raise Not_found
else
!str_idx - !what_idx
let sub_start str len =
let str_len = String.length str in
if len >= str_len then
""
else
String.sub str len (str_len - len)
let sub_end ?(offset=0) str len =
let str_len = String.length str in
if len >= str_len then
""
else
String.sub str 0 (str_len - len)
let starts_with ~what ?(offset=0) str =
let what_idx = ref 0 in
let str_idx = ref offset in
let ok = ref true in
while !ok &&
!str_idx < String.length str &&
!what_idx < String.length what do
if str.[!str_idx] = what.[!what_idx] then
incr what_idx
else
ok := false;
incr str_idx
done;
if !what_idx = String.length what then
true
else
false
let strip_starts_with ~what str =
if starts_with ~what str then
sub_start str (String.length what)
else
raise Not_found
let ends_with ~what ?(offset=0) str =
let what_idx = ref ((String.length what) - 1) in
let str_idx = ref ((String.length str) - 1) in
let ok = ref true in
while !ok &&
offset <= !str_idx &&
0 <= !what_idx do
if str.[!str_idx] = what.[!what_idx] then
decr what_idx
else
ok := false;
decr str_idx
done;
if !what_idx = -1 then
true
else
false
let strip_ends_with ~what str =
if ends_with ~what str then
sub_end str (String.length what)
else
raise Not_found
let replace_chars f s =
let buf = Buffer.create (String.length s) in
String.iter (fun c -> Buffer.add_char buf (f c)) s;
Buffer.contents buf
let lowercase_ascii =
replace_chars
(fun c ->
if (c >= 'A' && c <= 'Z') then
Char.chr (Char.code c + 32)
else
c)
let uncapitalize_ascii s =
if s <> "" then
(lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
else
s
let uppercase_ascii =
replace_chars
(fun c ->
if (c >= 'a' && c <= 'z') then
Char.chr (Char.code c - 32)
else
c)
let capitalize_ascii s =
if s <> "" then
(uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
else
s
end
module OASISExpr = struct
(* # 22 "src/oasis/OASISExpr.ml" *)
@ -129,7 +289,7 @@ module OASISExpr = struct
end
# 132 "myocamlbuild.ml"
# 292 "myocamlbuild.ml"
module BaseEnvLight = struct
(* # 22 "src/base/BaseEnvLight.ml" *)
@ -234,7 +394,7 @@ module BaseEnvLight = struct
end
# 237 "myocamlbuild.ml"
# 397 "myocamlbuild.ml"
module MyOCamlbuildFindlib = struct
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
@ -516,7 +676,7 @@ module MyOCamlbuildBase = struct
| nm, [], intf_modules ->
ocaml_lib nm;
let cmis =
List.map (fun m -> (String.uncapitalize m) ^ ".cmi")
List.map (fun m -> (OASISString.uncapitalize_ascii m) ^ ".cmi")
intf_modules in
dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
| nm, dir :: tl, intf_modules ->
@ -529,7 +689,7 @@ module MyOCamlbuildBase = struct
["compile"; "infer_interface"; "doc"])
tl;
let cmis =
List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi")
List.map (fun m -> dir^"/"^(OASISString.uncapitalize_ascii m)^".cmi")
intf_modules in
dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
cmis)
@ -603,19 +763,25 @@ module MyOCamlbuildBase = struct
end
# 606 "myocamlbuild.ml"
# 766 "myocamlbuild.ml"
open Ocamlbuild_plugin;;
let package_default =
{
MyOCamlbuildBase.lib_ocaml =
[
("sequence", [], []);
("invert", ["invert"], []);
("bigarray", ["bigarray"], [])
("sequence", ["src"], []);
("invert", ["src/invert"], []);
("bigarray", ["src/bigarray"], [])
];
lib_c = [];
flags = [];
includes = []
includes =
[
("src/invert", ["src"]);
("src/bigarray", ["src"]);
("qtest", ["src"]);
("bench", ["src"])
]
}
;;
@ -623,6 +789,6 @@ let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
# 627 "myocamlbuild.ml"
# 793 "myocamlbuild.ml"
(* OASIS_STOP *)
Ocamlbuild_plugin.dispatch dispatch_default;;

3
opam
View file

@ -1,8 +1,9 @@
opam-version: "1.2"
name: "sequence"
version: "0.7"
version: "0.8"
author: "Simon Cruanes"
maintainer: "simon.cruanes@inria.fr"
license: "BSD-2-clauses"
build: [
["./configure" "--disable-docs"
"--%{delimcc:enable}%-invert"

View file

@ -1,5 +1,5 @@
# OASIS_START
# DO NOT EDIT (digest: 8c0ffebbdb3e063d4b3e5cc00517b199)
Sequence
SequenceLabels
# DO NOT EDIT (digest: 5ddf4abb4ebf6a133d6ce26868d8dbf0)
src/Sequence
src/SequenceLabels
# OASIS_STOP

View file

@ -1 +0,0 @@
include Sequence

View file

@ -1,9 +1,9 @@
(* setup.ml generated for the first time by OASIS v0.4.4 *)
(* OASIS_START *)
(* DO NOT EDIT (digest: e28e259a63b26395383267decca6401e) *)
(* DO NOT EDIT (digest: 22604e4a6a5b4cfdf26c5f4f4ed84058) *)
(*
Regenerated by OASIS v0.4.5
Regenerated by OASIS v0.4.6
Visit http://oasis.forge.ocamlcore.org for more information and
documentation about functions used in this file.
*)
@ -246,6 +246,33 @@ module OASISString = struct
String.iter (fun c -> Buffer.add_char buf (f c)) s;
Buffer.contents buf
let lowercase_ascii =
replace_chars
(fun c ->
if (c >= 'A' && c <= 'Z') then
Char.chr (Char.code c + 32)
else
c)
let uncapitalize_ascii s =
if s <> "" then
(lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
else
s
let uppercase_ascii =
replace_chars
(fun c ->
if (c >= 'a' && c <= 'z') then
Char.chr (Char.code c - 32)
else
c)
let capitalize_ascii s =
if s <> "" then
(uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
else
s
end
@ -315,19 +342,15 @@ module OASISUtils = struct
let compare_csl s1 s2 =
String.compare (String.lowercase s1) (String.lowercase s2)
String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2)
module HashStringCsl =
Hashtbl.Make
(struct
type t = string
let equal s1 s2 =
(String.lowercase s1) = (String.lowercase s2)
let hash s =
Hashtbl.hash (String.lowercase s)
let equal s1 s2 = (compare_csl s1 s2) = 0
let hash s = Hashtbl.hash (OASISString.lowercase_ascii s)
end)
module SetStringCsl =
@ -365,7 +388,7 @@ module OASISUtils = struct
else
buf
in
String.lowercase buf
OASISString.lowercase_ascii buf
end
@ -471,7 +494,7 @@ module PropList = struct
order = Queue.create ();
name_norm =
(if case_insensitive then
String.lowercase
OASISString.lowercase_ascii
else
fun s -> s);
}
@ -1822,13 +1845,13 @@ module OASISUnixPath = struct
let capitalize_file f =
let dir = dirname f in
let base = basename f in
concat dir (String.capitalize base)
concat dir (OASISString.capitalize_ascii base)
let uncapitalize_file f =
let dir = dirname f in
let base = basename f in
concat dir (String.uncapitalize base)
concat dir (OASISString.uncapitalize_ascii base)
end
@ -2890,7 +2913,7 @@ module OASISFileUtil = struct
end
# 2893 "setup.ml"
# 2916 "setup.ml"
module BaseEnvLight = struct
(* # 22 "src/base/BaseEnvLight.ml" *)
@ -2995,7 +3018,7 @@ module BaseEnvLight = struct
end
# 2998 "setup.ml"
# 3021 "setup.ml"
module BaseContext = struct
(* # 22 "src/base/BaseContext.ml" *)
@ -5406,7 +5429,7 @@ module BaseSetup = struct
end
# 5409 "setup.ml"
# 5432 "setup.ml"
module InternalConfigurePlugin = struct
(* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
@ -5845,8 +5868,8 @@ module InternalInstallPlugin = struct
let make_fnames modul sufx =
List.fold_right
begin fun sufx accu ->
(String.capitalize modul ^ sufx) ::
(String.uncapitalize modul ^ sufx) ::
(OASISString.capitalize_ascii modul ^ sufx) ::
(OASISString.uncapitalize_ascii modul ^ sufx) ::
accu
end
sufx
@ -6270,7 +6293,7 @@ module InternalInstallPlugin = struct
end
# 6273 "setup.ml"
# 6296 "setup.ml"
module OCamlbuildCommon = struct
(* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
@ -6648,7 +6671,7 @@ module OCamlbuildDocPlugin = struct
end
# 6651 "setup.ml"
# 6674 "setup.ml"
module CustomPlugin = struct
(* # 22 "src/plugins/custom/CustomPlugin.ml" *)
@ -6796,7 +6819,7 @@ module CustomPlugin = struct
end
# 6799 "setup.ml"
# 6822 "setup.ml"
open OASISTypes;;
let setup_t =
@ -6809,7 +6832,7 @@ let setup_t =
CustomPlugin.Test.main
{
CustomPlugin.cmd_main =
[(OASISExpr.EBool true, ("make", ["run-tests"]))];
[(OASISExpr.EBool true, ("./run_qtest.native", []))];
cmd_clean = [(OASISExpr.EBool true, None)];
cmd_distclean = [(OASISExpr.EBool true, None)]
})
@ -6829,7 +6852,7 @@ let setup_t =
CustomPlugin.Test.clean
{
CustomPlugin.cmd_main =
[(OASISExpr.EBool true, ("make", ["run-tests"]))];
[(OASISExpr.EBool true, ("./run_qtest.native", []))];
cmd_clean = [(OASISExpr.EBool true, None)];
cmd_distclean = [(OASISExpr.EBool true, None)]
})
@ -6847,7 +6870,7 @@ let setup_t =
CustomPlugin.Test.distclean
{
CustomPlugin.cmd_main =
[(OASISExpr.EBool true, ("make", ["run-tests"]))];
[(OASISExpr.EBool true, ("./run_qtest.native", []))];
cmd_clean = [(OASISExpr.EBool true, None)];
cmd_distclean = [(OASISExpr.EBool true, None)]
})
@ -6892,7 +6915,8 @@ let setup_t =
build_type = (`Build, "ocamlbuild", Some "0.4");
build_custom =
{
pre_command = [(OASISExpr.EBool true, None)];
pre_command =
[(OASISExpr.EBool true, Some (("make", ["qtest-gen"])))];
post_command = [(OASISExpr.EBool true, None)]
};
install_type = (`Install, "internal", Some "0.4");
@ -6961,7 +6985,7 @@ let setup_t =
{
bs_build = [(OASISExpr.EBool true, true)];
bs_install = [(OASISExpr.EBool true, true)];
bs_path = ".";
bs_path = "src/";
bs_compiled_object = Best;
bs_build_depends = [FindlibPackage ("bytes", None)];
bs_build_tools = [ExternalTool "ocamlbuild"];
@ -6999,7 +7023,7 @@ let setup_t =
(OASISExpr.EBool true, false);
(OASISExpr.EFlag "invert", true)
];
bs_path = "invert";
bs_path = "src/invert";
bs_compiled_object = Best;
bs_build_depends =
[
@ -7041,7 +7065,7 @@ let setup_t =
(OASISExpr.EBool true, false);
(OASISExpr.EFlag "bigarray", true)
];
bs_path = "bigarray";
bs_path = "src/bigarray";
bs_compiled_object = Best;
bs_build_depends =
[
@ -7096,7 +7120,7 @@ let setup_t =
});
Executable
({
cs_name = "run_tests";
cs_name = "run_qtest";
cs_data = PropList.Data.create ();
cs_plugin_data = []
},
@ -7107,12 +7131,12 @@ let setup_t =
(OASISExpr.EFlag "tests", true)
];
bs_install = [(OASISExpr.EBool true, false)];
bs_path = "tests/";
bs_path = "qtest/";
bs_compiled_object = Native;
bs_build_depends =
[
InternalLibrary "sequence";
FindlibPackage ("oUnit", None)
FindlibPackage ("qcheck", None)
];
bs_build_tools = [ExternalTool "ocamlbuild"];
bs_c_sources = [];
@ -7124,7 +7148,7 @@ let setup_t =
bs_byteopt = [(OASISExpr.EBool true, [])];
bs_nativeopt = [(OASISExpr.EBool true, [])]
},
{exec_custom = false; exec_main_is = "run_tests.ml"});
{exec_custom = false; exec_main_is = "run_qtest.ml"});
Test
({
cs_name = "all";
@ -7134,7 +7158,7 @@ let setup_t =
{
test_type = (`Test, "custom", Some "0.4");
test_command =
[(OASISExpr.EBool true, ("make", ["run-tests"]))];
[(OASISExpr.EBool true, ("./run_qtest.native", []))];
test_custom =
{
pre_command = [(OASISExpr.EBool true, None)];
@ -7153,7 +7177,7 @@ let setup_t =
test_tools =
[
ExternalTool "ocamlbuild";
InternalExecutable "run_tests"
InternalExecutable "run_qtest"
]
});
Executable
@ -7279,8 +7303,8 @@ let setup_t =
plugin_data = []
};
oasis_fn = Some "_oasis";
oasis_version = "0.4.5";
oasis_digest = Some "\247\213|\155\007DgsAe\210\221|\198\232\237";
oasis_version = "0.4.6";
oasis_digest = Some "r\242\252(l\210\150\168\252\213\181\209 *[\200";
oasis_exec = None;
oasis_setup_args = [];
setup_update = false
@ -7288,6 +7312,6 @@ let setup_t =
let setup () = BaseSetup.setup setup_t;;
# 7292 "setup.ml"
# 7316 "setup.ml"
(* OASIS_STOP *)
let () = setup ();;

33
src/META Normal file
View file

@ -0,0 +1,33 @@
# OASIS_START
# DO NOT EDIT (digest: 8041ba3970fcecd2b690dc7b78ccae41)
version = "0.7"
description = "Simple sequence (iterator) datatype and combinators"
requires = "bytes"
archive(byte) = "sequence.cma"
archive(byte, plugin) = "sequence.cma"
archive(native) = "sequence.cmxa"
archive(native, plugin) = "sequence.cmxs"
exists_if = "sequence.cma"
package "invert" (
version = "0.7"
description = "Simple sequence (iterator) datatype and combinators"
requires = "sequence delimcc"
archive(byte) = "invert.cma"
archive(byte, plugin) = "invert.cma"
archive(native) = "invert.cmxa"
archive(native, plugin) = "invert.cmxs"
exists_if = "invert.cma"
)
package "bigarray" (
version = "0.7"
description = "Simple sequence (iterator) datatype and combinators"
requires = "sequence bigarray"
archive(byte) = "bigarray.cma"
archive(byte, plugin) = "bigarray.cma"
archive(native) = "bigarray.cmxa"
archive(native, plugin) = "bigarray.cmxs"
exists_if = "bigarray.cma"
)
# OASIS_STOP

View file

@ -0,0 +1,4 @@
# OASIS_START
# DO NOT EDIT (digest: dca476c3b57e859aa3b1c75ec0959ed9)
SequenceBigarray
# OASIS_STOP

View file

@ -0,0 +1,4 @@
# OASIS_START
# DO NOT EDIT (digest: dca476c3b57e859aa3b1c75ec0959ed9)
SequenceBigarray
# OASIS_STOP

View file

@ -0,0 +1,4 @@
# OASIS_START
# DO NOT EDIT (digest: d74492d261fcc87665b60e0331c04236)
SequenceInvert
# OASIS_STOP

4
src/invert/invert.mllib Normal file
View file

@ -0,0 +1,4 @@
# OASIS_START
# DO NOT EDIT (digest: d74492d261fcc87665b60e0331c04236)
SequenceInvert
# OASIS_STOP

View file

@ -11,6 +11,10 @@ type 'a sequence = 'a t
type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
(** Sequence of pairs of values of type ['a] and ['b]. *)
(*$inject
let pp_ilist = Q.Print.(list int)
*)
(** Build a sequence from a iter function *)
let from_iter f = f
@ -20,6 +24,13 @@ let rec from_fun f k = match f () with
let empty _ = ()
(*$R
let seq = empty in
OUnit.assert_bool "empty" (is_empty seq);
OUnit.assert_bool "empty"
(try iter (fun _ -> raise Exit) seq; true with Exit -> false);
*)
let singleton x k = k x
let return x k = k x
let pure f k = k f
@ -31,6 +42,12 @@ let snoc l x k = l k; k x
let repeat x k = while true do k x done
(*$R
let seq = repeat "hello" in
OUnit.assert_equal ["hello"; "hello"; "hello"]
(seq |> take 3 |> to_list);
*)
let rec iterate f x k =
k x;
iterate f (f x) k
@ -55,6 +72,12 @@ let fold f init seq =
seq (fun elt -> r := f !r elt);
!r
(*$R
let n = (1 -- 10)
|> fold (+) 0 in
OUnit.assert_equal 55 n;
*)
let foldi f init seq =
let i = ref 0 in
let r = ref init in
@ -64,6 +87,13 @@ let foldi f init seq =
incr i);
!r
(*$R
let l = ["hello"; "world"]
|> of_list
|> foldi (fun acc i x -> (i,x) :: acc) [] in
OUnit.assert_equal [1, "world"; 0, "hello"] l;
*)
let map f seq k = seq (fun x -> k (f x))
let mapi f seq k =
@ -86,12 +116,37 @@ let append s1 s2 k = s1 k; s2 k
let concat s k = s (fun s' -> s' k)
(*$R
let s1 = (1 -- 5) in
let s2 = (6 -- 10) in
let l = [1;2;3;4;5;6;7;8;9;10] in
OUnit.assert_equal l (to_list (append s1 s2));
*)
(*$R
(1 -- 1000)
|> map (fun i -> i -- (i+1))
|> concat
|> length
|> OUnit.assert_equal 2000
*)
let flatten s = concat s
let flatMap f seq k = seq (fun x -> f x k)
let flat_map = flatMap
(*$R
(1 -- 1000)
|> flat_map (fun i -> i -- (i+1))
|> length
|> OUnit.assert_equal 2000
*)
let flat_map_l f seq k =
seq (fun x -> List.iter k (f x))
let fmap f seq k =
seq (fun x -> match f x with
| None -> ()
@ -104,6 +159,14 @@ let intersperse elem seq k =
let first = ref true in
seq (fun x -> (if !first then first := false else k elem); k x)
(*$R
(1 -- 100)
|> (fun seq -> intersperse 0 seq)
|> take 10
|> to_list
|> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0]
*)
(** Mutable unrolled list to serve as intermediate storage *)
module MList = struct
type 'a node =
@ -204,6 +267,35 @@ let persistent seq =
let l = MList.of_seq seq in
MList.to_seq l
(*$R
let printer = pp_ilist in
let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
let seq = of_stream stream in
OUnit.assert_equal ~printer [0;1;2;3;4] (seq |> to_list);
OUnit.assert_equal ~printer [] (seq |> to_list);
*)
(*$R
let printer = pp_ilist in
let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
let seq = of_stream stream in
(* consume seq into a persistent version of itself *)
let seq' = persistent seq in
OUnit.assert_equal ~printer [] (seq |> to_list);
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_list);
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_list);
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_stream |> of_stream |> to_list);
*)
(*$R
let printer = pp_ilist in
let seq = (0 -- 10_000) in
let seq' = persistent seq in
OUnit.assert_equal 10_001 (length seq');
OUnit.assert_equal 10_001 (length seq');
OUnit.assert_equal ~printer [0;1;2;3] (seq' |> take 4 |> to_list);
*)
type 'a lazy_state =
| LazySuspend
| LazyCached of 'a t
@ -224,6 +316,14 @@ let sort ?(cmp=Pervasives.compare) seq =
let l = List.fast_sort cmp l in
fun k -> List.iter k l
(*$R
(1 -- 100)
|> sort ~cmp:(fun i j -> j - i)
|> take 4
|> to_list
|> OUnit.assert_equal [100;99;98;97]
*)
let group_succ_by ?(eq=fun x y -> x = y) seq k =
let cur = ref [] in
seq (fun x ->
@ -239,6 +339,12 @@ let group_succ_by ?(eq=fun x y -> x = y) seq k =
let group = group_succ_by
(*$R
[1;2;3;3;2;2;3;4]
|> of_list |> group_succ_by ?eq:None |> to_list
|> OUnit.assert_equal [[1];[2];[3;3];[2;2];[3];[4]]
*)
let group_by (type k) ?(hash=Hashtbl.hash) ?(eq=(=)) seq =
let module Tbl = Hashtbl.Make(struct
type t = k
@ -255,6 +361,12 @@ let group_by (type k) ?(hash=Hashtbl.hash) ?(eq=(=)) seq =
fun yield ->
Tbl.iter (fun _ l -> yield l) tbl
(*$R
[1;2;3;3;2;2;3;4]
|> of_list |> group_by ?eq:None ?hash:None |> sort ?cmp:None |> to_list
|> OUnit.assert_equal [[1];[2;2;2];[3;3;3];[4]]
*)
let uniq ?(eq=fun x y -> x = y) seq k =
let has_prev = ref false
and prev = ref (Obj.magic 0) in (* avoid option type, costly *)
@ -268,6 +380,12 @@ let uniq ?(eq=fun x y -> x = y) seq k =
k x
))
(*$R
[1;2;2;3;4;4;4;3;3]
|> of_list |> uniq ?eq:None |> to_list
|> OUnit.assert_equal [1;2;3;4;3]
*)
let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq =
let module S = Set.Make(struct
type t = elt
@ -276,9 +394,28 @@ let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq =
let set = fold (fun acc x -> S.add x acc) S.empty seq in
fun k -> S.iter k set
(*$R
[42;1;2;3;4;5;4;3;2;1]
|> of_list
|> sort_uniq ?cmp:None
|> to_list
|> OUnit.assert_equal [1;2;3;4;5;42]
*)
let product outer inner k =
outer (fun x -> inner (fun y -> k (x,y)))
(*$R
let stream = Stream.from (fun i -> if i < 3 then Some i else None) in
let a = of_stream stream in
let b = of_list ["a";"b";"c"] in
let s = product a b |> map (fun (x,y) -> y,x)
|> to_list |> List.sort compare in
OUnit.assert_equal ["a",0; "a", 1; "a", 2;
"b",0; "b", 1; "b", 2;
"c",0; "c", 1; "c", 2;] s
*)
let product2 outer inner k =
outer (fun x -> inner (fun y -> k x y))
@ -289,17 +426,41 @@ let join ~join_row s1 s2 k =
| None -> ()
| Some c -> k c))
(*$R
let s1 = (1 -- 3) in
let s2 = of_list ["1"; "2"] in
let join_row i j =
if string_of_int i = j then Some (string_of_int i ^ " = " ^ j) else None
in
let s = join ~join_row s1 s2 in
OUnit.assert_equal ["1 = 1"; "2 = 2"] (to_list s);
*)
let rec unfoldr f b k = match f b with
| None -> ()
| Some (x, b') ->
k x;
unfoldr f b' k
(*$R
let f x = if x < 5 then Some (string_of_int x,x+1) else None in
unfoldr f 0
|> to_list
|> OUnit.assert_equal ["0"; "1"; "2"; "3"; "4"]
*)
let scan f acc seq k =
k acc;
let acc = ref acc in
seq (fun elt -> let acc' = f !acc elt in k acc'; acc := acc')
(*$R
(1 -- 5)
|> scan (+) 0
|> to_list
|> OUnit.assert_equal ~printer:pp_ilist [0;1;3;6;10;15]
*)
let max ?(lt=fun x y -> x < y) seq =
let ret = ref None in
seq
@ -341,6 +502,13 @@ let take n seq k =
k x)
with ExitTake -> ()
(*$R
let l = to_list (take 0 (of_list [1])) in
OUnit.assert_equal ~printer:pp_ilist [] l;
let l = to_list (take 5 (of_list [1;2;3;4;5;6;7;8;9;10])) in
OUnit.assert_equal ~printer:pp_ilist [1;2;3;4;5] l;
*)
exception ExitTakeWhile
let take_while p seq k =
@ -362,11 +530,20 @@ let fold_while f s seq =
try
seq consume; !state
with ExitFoldWhile -> !state
(*$R
let n = of_list [true;true;false;true]
|> fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 in
OUnit.assert_equal 2 n;
*)
let drop n seq k =
let count = ref 0 in
seq (fun x -> if !count >= n then k x else incr count)
(*$R
(1 -- 5) |> drop 2 |> to_list |> OUnit.assert_equal [3;4;5]
*)
let drop_while p seq k =
let drop = ref true in
seq
@ -379,6 +556,10 @@ let rev seq =
let l = MList.of_seq seq in
fun k -> MList.iter_rev k l
(*$R
(1 -- 5) |> rev |> to_list |> OUnit.assert_equal [5;4;3;2;1]
*)
exception ExitForall
let for_all p seq =
@ -387,6 +568,16 @@ let for_all p seq =
true
with ExitForall -> false
(*$R
OUnit.assert_bool "true" (for_all (fun x -> x < 10) (1--9));
OUnit.assert_bool "false" (not (for_all (fun x -> x < 10) (2--11)));
OUnit.assert_bool "true" (for_all (fun _ -> false) empty);
OUnit.assert_bool "nested"
(for_all
(fun seq -> not (for_all (fun x -> x < 8) seq))
(1 -- 10 >|= fun x -> x--20));
*)
exception ExitExists
(** Exists there some element satisfying the predicate? *)
@ -396,6 +587,16 @@ let exists p seq =
false
with ExitExists -> true
(*$R
(1 -- 100)
|> exists (fun x -> x = 59)
|> OUnit.assert_bool "exists";
(1 -- 100)
|> exists (fun x -> x < 0)
|> (fun x -> not x)
|> OUnit.assert_bool "not exists";
*)
let mem ?(eq=(=)) x seq = exists (eq x) seq
exception ExitFind
@ -417,6 +618,10 @@ let length seq =
seq (fun _ -> incr r);
!r
(*$R
(1 -- 1000) |> length |> OUnit.assert_equal 1000
*)
exception ExitIsEmpty
let is_empty seq =
@ -519,6 +724,15 @@ let of_queue q k = Queue.iter k q
let hashtbl_add h seq =
seq (fun (k,v) -> Hashtbl.add h k v)
(*$R
let h = (1 -- 5)
|> zip_i
|> to_hashtbl2 in
(0 -- 4)
|> iter (fun i -> OUnit.assert_equal (i+1) (Hashtbl.find h i));
OUnit.assert_equal [0;1;2;3;4] (hashtbl_keys h |> sort ?cmp:None |> to_list);
*)
let hashtbl_replace h seq =
seq (fun (k,v) -> Hashtbl.replace h k v)
@ -570,13 +784,50 @@ let of_in_channel ic =
let to_buffer seq buf =
seq (fun c -> Buffer.add_char buf c)
(*$R
let b = Buffer.create 4 in
"hello world"
|> of_str |> rev |> map Char.uppercase
|> (fun seq -> to_buffer seq b);
OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
*)
(** Iterator on integers in [start...stop] by steps 1 *)
let int_range ~start ~stop k =
for i = start to stop do k i done
(*$R
OUnit.assert_equal ~printer:pp_ilist [1;2;3;4] (to_list (1--4));
OUnit.assert_equal ~printer:pp_ilist [10;9;8;7;6] (to_list (10 --^ 6));
OUnit.assert_equal ~printer:pp_ilist [] (to_list (10--4));
OUnit.assert_equal ~printer:pp_ilist [] (to_list (10 --^ 60));
*)
let int_range_dec ~start ~stop k =
for i = start downto stop do k i done
let int_range_by ~step i j yield =
if step=0 then invalid_arg "int_range_by";
for k = 0 to (j - i) / step do
yield (k * step + i)
done
(*$= & ~printer:Q.Print.(list int)
[1;2;3;4] (int_range_by ~step:1 1 4 |> to_list)
[4;3;2;1] (int_range_by ~step:~-1 4 1 |> to_list)
[6;4;2] (int_range_by 6 1 ~step:~-2 |> to_list)
[] (int_range_by ~step:1 4 1 |> to_list)
*)
(*$Q
Q.(pair small_int small_int) (fun (i,j) -> \
let i = Pervasives.min i j and j = Pervasives.max i j in \
(i--j |> to_list) = (int_range_by ~step:1 i j |> to_list))
Q.(pair small_int small_int) (fun (i,j) -> \
let i = Pervasives.min i j and j = Pervasives.max i j in \
(i--j |> to_rev_list) = (int_range_by ~step:~-1 j i |> to_list))
*)
let bools k = k false; k true
let of_set (type s) (type v) m set =
@ -856,3 +1107,10 @@ module IO = struct
let write_lines ?mode ?flags filename seq =
write_bytes_lines ?mode ?flags filename (map Bytes.unsafe_of_string seq)
end
(* regression tests *)
(*$R
let s = (take 10 (repeat 1)) in
OUnit.assert_bool "not empty" (not (is_empty s));
*)

5
src/sequence.mldylib Normal file
View file

@ -0,0 +1,5 @@
# OASIS_START
# DO NOT EDIT (digest: 8c0ffebbdb3e063d4b3e5cc00517b199)
Sequence
SequenceLabels
# OASIS_STOP

View file

@ -158,6 +158,10 @@ val flat_map : ('a -> 'b t) -> 'a t -> 'b t
element of the initial sequence, and calls {!concat}.
@since 0.5 *)
val flat_map_l : ('a -> 'b list) -> 'a t -> 'b t
(** Convenience function combining {!flat_map} and {!of_list}
@since 0.8 *)
val fmap : ('a -> 'b option) -> 'a t -> 'b t
(** @deprecated use {!filter_map} since 0.6 *)
@ -417,6 +421,12 @@ val int_range_dec : start:int -> stop:int -> int t
(** Iterator on decreasing integers in [stop...start] by steps -1.
See {!(--^)} for an infix version *)
val int_range_by : step:int -> int -> int -> int t
(** [int_range_by ~step i j] is the range starting at [i], including [j],
where the difference between successive elements is [step].
use a negative [step] for a decreasing sequence.
@raise Invalid_argument if [step=0] *)
val bools : bool t
(** Iterates on [true] and [false]
@since 0.7 *)

5
src/sequence.mllib Normal file
View file

@ -0,0 +1,5 @@
# OASIS_START
# DO NOT EDIT (digest: 8c0ffebbdb3e063d4b3e5cc00517b199)
Sequence
SequenceLabels
# OASIS_STOP

1116
src/sequenceLabels.ml Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
open OUnit
let suite =
"run_tests" >:::
[ Test_sequence.suite; ]
let _ =
OUnit.run_test_tt_main suite

View file

@ -1,263 +0,0 @@
open OUnit
module S = Sequence
let pp_ilist l =
let b = Buffer.create 15 in
let fmt = Format.formatter_of_buffer b in
Format.fprintf fmt "@[<h>%a@]" (S.pp_seq Format.pp_print_int) (S.of_list l);
Buffer.contents b
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);
()
let test_repeat () =
let seq = S.repeat "hello" in
OUnit.assert_equal ["hello"; "hello"; "hello"]
(seq |> S.take 3 |> S.to_list);
()
let test_concat () =
let s1 = S.(1 -- 5) in
let s2 = S.(6 -- 10) in
let l = [1;2;3;4;5;6;7;8;9;10] in
OUnit.assert_equal l (S.to_list (S.append s1 s2));
()
let test_fold () =
let n = S.(1 -- 10)
|> S.fold (+) 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
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
OUnit.assert_equal 2 n;
()
let test_exists () =
S.(1 -- 100)
|> S.exists (fun x -> x = 59)
|> OUnit.assert_bool "exists";
S.(1 -- 100)
|> S.exists (fun x -> x < 0)
|> (fun x -> not x)
|> OUnit.assert_bool "not exists";
()
let test_length () =
S.(1 -- 1000) |> S.length |> OUnit.assert_equal 1000
let test_concat2 () =
S.(1 -- 1000)
|> S.map (fun i -> S.(i -- (i+1)))
|> S.concat
|> S.length
|> OUnit.assert_equal 2000
let test_flat_map () =
S.(1 -- 1000)
|> S.flat_map (fun i -> S.(i -- (i+1)))
|> S.length
|> OUnit.assert_equal 2000
let test_intersperse () =
S.(1 -- 100)
|> (fun seq -> S.intersperse 0 seq)
|> S.take 10
|> S.to_list
|> OUnit.assert_equal [1;0;2;0;3;0;4;0;5;0]
let test_not_persistent () =
let printer = pp_ilist in
let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
let seq = S.of_stream stream in
OUnit.assert_equal ~printer [0;1;2;3;4] (seq |> S.to_list);
OUnit.assert_equal ~printer [] (seq |> S.to_list);
()
let test_persistent () =
let printer = pp_ilist in
let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
let seq = S.of_stream stream in
(* consume seq into a persistent version of itself *)
let seq' = S.persistent seq in
OUnit.assert_equal ~printer [] (seq |> S.to_list);
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_list);
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_list);
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> S.to_stream |> S.of_stream |> S.to_list);
()
let test_big_persistent () =
let printer = pp_ilist in
let seq = S.(0 -- 10_000) in
let seq' = S.persistent seq in
OUnit.assert_equal 10_001 (S.length seq');
OUnit.assert_equal 10_001 (S.length seq');
OUnit.assert_equal ~printer [0;1;2;3] (seq' |> S.take 4 |> S.to_list);
()
let test_sort () =
S.(1 -- 100)
|> S.sort ~cmp:(fun i j -> j - i)
|> S.take 4
|> S.to_list
|> OUnit.assert_equal [100;99;98;97]
let test_sort_uniq () =
[42;1;2;3;4;5;4;3;2;1]
|> S.of_list
|> S.sort_uniq ?cmp:None
|> S.to_list
|> OUnit.assert_equal [1;2;3;4;5;42]
let test_group_succ () =
[1;2;3;3;2;2;3;4]
|> S.of_list |> S.group_succ_by ?eq:None |> S.to_list
|> OUnit.assert_equal [[1];[2];[3;3];[2;2];[3];[4]]
let test_group_by () =
[1;2;3;3;2;2;3;4]
|> S.of_list |> S.group_by ?eq:None ?hash:None |> S.sort ?cmp:None |> S.to_list
|> OUnit.assert_equal [[1];[2;2;2];[3;3;3];[4]]
let test_uniq () =
[1;2;2;3;4;4;4;3;3]
|> S.of_list |> S.uniq ?eq:None |> S.to_list
|> OUnit.assert_equal [1;2;3;4;3]
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)
|> S.to_list |> List.sort compare in
OUnit.assert_equal ["a",0; "a", 1; "a", 2;
"b",0; "b", 1; "b", 2;
"c",0; "c", 1; "c", 2;] s
let test_join () =
let s1 = S.(1 -- 3) in
let s2 = S.of_list ["1"; "2"] in
let join_row i j =
if string_of_int i = j then Some (string_of_int i ^ " = " ^ j) else None
in
let s = S.join ~join_row s1 s2 in
OUnit.assert_equal ["1 = 1"; "2 = 2"] (S.to_list s);
()
let test_scan () =
S.(1 -- 5)
|> S.scan (+) 0
|> S.to_list
|> OUnit.assert_equal ~printer:pp_ilist [0;1;3;6;10;15]
let test_drop () =
S.(1 -- 5) |> S.drop 2 |> S.to_list |> OUnit.assert_equal [3;4;5]
let test_rev () =
S.(1 -- 5) |> S.rev |> S.to_list |> OUnit.assert_equal [5;4;3;2;1]
let test_unfoldr () =
let f x = if x < 5 then Some (string_of_int x,x+1) else None in
S.unfoldr f 0
|> S.to_list
|> OUnit.assert_equal ["0"; "1"; "2"; "3"; "4"]
let test_hashtbl () =
let h = S.(1 -- 5)
|> S.zip_i
|> S.to_hashtbl2 in
S.(0 -- 4)
|> S.iter (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
|> (fun seq -> S.to_buffer seq b);
OUnit.assert_equal "DLROW OLLEH" (Buffer.contents b);
()
let test_int_range () =
OUnit.assert_equal ~printer:pp_ilist [1;2;3;4] S.(to_list (1--4));
OUnit.assert_equal ~printer:pp_ilist [10;9;8;7;6] S.(to_list (10 --^ 6));
OUnit.assert_equal ~printer:pp_ilist [] S.(to_list (10--4));
OUnit.assert_equal ~printer:pp_ilist [] S.(to_list (10 --^ 60));
()
let test_take () =
let l = S.(to_list (take 0 (of_list [1]))) in
OUnit.assert_equal ~printer:pp_ilist [] l;
let l = S.(to_list (take 5 (of_list [1;2;3;4;5;6;7;8;9;10]))) in
OUnit.assert_equal ~printer:pp_ilist [1;2;3;4;5] l;
()
let test_for_all () =
OUnit.assert_bool "true" S.(for_all (fun x -> x < 10) (1--9));
OUnit.assert_bool "false" S.(not (for_all (fun x -> x < 10) (2--11)));
OUnit.assert_bool "true" S.(for_all (fun _ -> false) empty);
OUnit.assert_bool "nested"
S.(
for_all
(fun seq ->
not (for_all (fun x -> x < 8) seq)
) (1 -- 10 >|= fun x -> x--20)
);
()
let test_regression1 () =
let s = S.(take 10 (repeat 1)) in
OUnit.assert_bool "not empty" (not (S.is_empty s));
()
let suite =
"test_sequence" >:::
[ "test_empty" >:: test_empty;
"test_repeat" >:: test_repeat;
"test_concat" >:: test_concat;
"test_concat2" >:: test_concat2;
"test_fold" >:: test_fold;
"test_foldi" >:: test_foldi;
"test_exists" >:: test_exists;
"test_length" >:: test_length;
"test_concat" >:: test_concat;
"test_flatMap" >:: test_flat_map;
"test_intersperse" >:: test_intersperse;
"test_not_persistent" >:: test_not_persistent;
"test_persistent" >:: test_persistent;
"test_big_persistent" >:: test_big_persistent;
"test_sort" >:: test_sort;
"test_sort_uniq" >:: test_sort_uniq;
"test_group_succ_by" >:: test_group_succ;
"test_group_by" >:: test_group_by;
"test_uniq" >:: test_uniq;
"test_product" >:: test_product;
"test_join" >:: test_join;
"test_scan" >:: test_scan;
"test_drop" >:: test_drop;
"test_rev" >:: test_rev;
"test_unfoldr" >:: test_unfoldr;
"test_hashtbl" >:: test_hashtbl;
"test_int_range" >:: test_int_range;
"test_take" >:: test_take;
"test_fold_while" >:: test_fold_while;
"test_buff" >:: test_buff;
"test_for_all" >:: test_for_all;
"test_regression1" >:: test_regression1;
]