From 5853cbf77995bad749f9e6a34107f2530071cdbd Mon Sep 17 00:00:00 2001 From: David Allsopp Date: Tue, 23 Oct 2018 08:31:26 +0100 Subject: [PATCH] Eliminate renames in patches (#3617) * Eliminate renames in patches * ensure that `patch` removes zero-length files This fixes the build on some platforms like Alpine where this behaviour is not active by default, and thus results in empty `.ml` files being generated in the source tree. Signed-off-by: Anil Madhavapeddy * Revert "ensure that `patch` removes zero-length files" This reverts commit f6d001761256eec3e9db640f82e377823b44be21. * Workaround strict POSIX patching POSIX patch will leave src_ext/seq/seq.ml{,i} as zero-length files but patch -E is non-POSIX. --- src_ext/Makefile | 2 +- src_ext/Makefile.sources | 4 + ...efinition-alias-module-depending-on-.patch | 370 ++++++++++++++++-- .../seq/0001-seq-0.2-for-jbuilder.patch | 366 +++++++++++++++-- 4 files changed, 679 insertions(+), 63 deletions(-) diff --git a/src_ext/Makefile b/src_ext/Makefile index 9fda3a7b95c..80d0f442fa6 100644 --- a/src_ext/Makefile +++ b/src_ext/Makefile @@ -57,7 +57,7 @@ else MD5CHECK = test "`md5sum $(1) | sed -e 's/^[^a-f0-9]*\([a-f0-9]*\).*/\1/'`" = "$(2)" || (rm $(1) && false) endif -lib-ext: clone +lib-ext: clone ensure-seq-patched.stamp @ ifeq ($(CAN_PKG),1) diff --git a/src_ext/Makefile.sources b/src_ext/Makefile.sources index 946ec41bc92..26b8ccb7f33 100644 --- a/src_ext/Makefile.sources +++ b/src_ext/Makefile.sources @@ -65,4 +65,8 @@ MD5_PKG_topkg = 8978a0595db1a22e4251ec62735d4b84 URL_seq = https://github.com/c-cube/seq/archive/0.1.tar.gz MD5_seq = 0e87f9709541ed46ecb6f414bc31458c +# This is necessary as long as a patch is used to rename seq.ml and seq.mli +ensure-seq-patched.stamp: seq.stamp + rm -f seq/src/seq.ml seq/src/seq.mli + $(call PKG_SAME,seq) diff --git a/src_ext/patches/seq.pkg/0001-switch-between-definition-alias-module-depending-on-.patch b/src_ext/patches/seq.pkg/0001-switch-between-definition-alias-module-depending-on-.patch index 2dd1369ea8e..456852bd8d0 100644 --- a/src_ext/patches/seq.pkg/0001-switch-between-definition-alias-module-depending-on-.patch +++ b/src_ext/patches/seq.pkg/0001-switch-between-definition-alias-module-depending-on-.patch @@ -1,24 +1,28 @@ From 2d608bd49647a4a6d0ec51c61cf63678212ea185 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Thu, 19 Apr 2018 00:08:23 -0500 -Subject: [PATCH 1/3] switch between definition/alias module depending on - ocaml's version +Subject: [PATCH] switch between definition/alias module depending on ocaml's + version --- - .gitignore | 2 ++ - Makefile | 11 ++++++++++- - select_version.ml | 14 ++++++++++++++ - seq.opam | 3 --- - src/seq_alias.ml | 1 + - src/seq_alias.mli | 2 ++ - src/{seq.ml => seq_redef.ml} | 0 - src/{seq.mli => seq_redef.mli} | 2 -- - 8 files changed, 29 insertions(+), 6 deletions(-) + .gitignore | 2 ++ + Makefile | 11 ++++++- + select_version.ml | 14 +++++++++ + seq.opam | 3 -- + src/seq.ml | 73 -------------------------------------------- + src/seq.mli | 77 ----------------------------------------------- + src/seq_alias.ml | 1 + + src/seq_alias.mli | 2 ++ + src/seq_redef.ml | 73 ++++++++++++++++++++++++++++++++++++++++++++ + src/seq_redef.mli | 75 +++++++++++++++++++++++++++++++++++++++++++++ + 10 files changed, 177 insertions(+), 154 deletions(-) create mode 100644 select_version.ml + delete mode 100644 src/seq.ml + delete mode 100644 src/seq.mli create mode 100644 src/seq_alias.ml create mode 100644 src/seq_alias.mli - rename src/{seq.ml => seq_redef.ml} (100%) - rename src/{seq.mli => seq_redef.mli} (99%) + create mode 100644 src/seq_redef.ml + create mode 100644 src/seq_redef.mli diff --git a/.gitignore b/.gitignore index e35d885..487f91e 100644 @@ -85,6 +89,168 @@ index 8d3569c..b75ca84 100644 -] +diff --git a/src/seq.ml b/src/seq.ml +deleted file mode 100644 +index ccdbfde..0000000 +--- a/src/seq.ml ++++ /dev/null +@@ -1,73 +0,0 @@ +-(**************************************************************************) +-(* *) +-(* OCaml *) +-(* *) +-(* Simon Cruanes *) +-(* *) +-(* Copyright 2017 Institut National de Recherche en Informatique et *) +-(* en Automatique. *) +-(* *) +-(* All rights reserved. This file is distributed under the terms of *) +-(* the GNU Lesser General Public License version 2.1, with the *) +-(* special exception on linking described in the file LICENSE. *) +-(* *) +-(**************************************************************************) +- +-(* Module [Seq]: functional iterators *) +- +-type +'a node = +- | Nil +- | Cons of 'a * 'a t +- +-and 'a t = unit -> 'a node +- +-let empty () = Nil +- +-let return x () = Cons (x, empty) +- +-let rec map f seq () = match seq() with +- | Nil -> Nil +- | Cons (x, next) -> Cons (f x, map f next) +- +-let rec filter_map f seq () = match seq() with +- | Nil -> Nil +- | Cons (x, next) -> +- match f x with +- | None -> filter_map f next () +- | Some y -> Cons (y, filter_map f next) +- +-let rec filter f seq () = match seq() with +- | Nil -> Nil +- | Cons (x, next) -> +- if f x +- then Cons (x, filter f next) +- else filter f next () +- +-let rec flat_map f seq () = match seq () with +- | Nil -> Nil +- | Cons (x, next) -> +- flat_map_app f (f x) next () +- +-(* this is [append seq (flat_map f tail)] *) +-and flat_map_app f seq tail () = match seq () with +- | Nil -> flat_map f tail () +- | Cons (x, next) -> +- Cons (x, flat_map_app f next tail) +- +-let fold_left f acc seq = +- let rec aux f acc seq = match seq () with +- | Nil -> acc +- | Cons (x, next) -> +- let acc = f acc x in +- aux f acc next +- in +- aux f acc seq +- +-let iter f seq = +- let rec aux seq = match seq () with +- | Nil -> () +- | Cons (x, next) -> +- f x; +- aux next +- in +- aux seq +diff --git a/src/seq.mli b/src/seq.mli +deleted file mode 100644 +index f33c19a..0000000 +--- a/src/seq.mli ++++ /dev/null +@@ -1,77 +0,0 @@ +-(**************************************************************************) +-(* *) +-(* OCaml *) +-(* *) +-(* Simon Cruanes *) +-(* *) +-(* Copyright 2017 Institut National de Recherche en Informatique et *) +-(* en Automatique. *) +-(* *) +-(* All rights reserved. This file is distributed under the terms of *) +-(* the GNU Lesser General Public License version 2.1, with the *) +-(* special exception on linking described in the file LICENSE. *) +-(* *) +-(**************************************************************************) +- +-(* Module [Seq]: functional iterators *) +- +-(** {1 Functional Iterators} *) +- +-(** The type ['a t] is a {b delayed list}, i.e. a list where some evaluation +- is needed to access the next element. This makes it possible to build +- infinite sequences, to build sequences as we traverse them, and to transform +- them in a lazy fashion rather than upfront. +-*) +- +-(** @since 4.07 *) +- +-type 'a t = unit -> 'a node +-(** The type of delayed lists containing elements of type ['a]. +- Note that the concrete list node ['a node] is delayed under a closure, +- not a [lazy] block, which means it might be recomputed every time +- we access it. *) +- +-and +'a node = +- | Nil +- | Cons of 'a * 'a t +-(** A fully-evaluated list node, either empty or containing an element +- and a delayed tail. *) +- +-val empty : 'a t +-(** The empty sequence, containing no elements. *) +- +-val return : 'a -> 'a t +-(** The singleton sequence containing only the given element. *) +- +-val map : ('a -> 'b) -> 'a t -> 'b t +-(** [map f seq] returns a new sequence whose elements are the elements of +- [seq], transformed by [f]. +- This transformation is lazy, it only applies when the result is traversed. +- +- If [seq = [1;2;3]], then [map f seq = [f 1; f 2; f 3]]. *) +- +-val filter : ('a -> bool) -> 'a t -> 'a t +-(** Remove from the sequence the elements that do not satisfy the +- given predicate. +- This transformation is lazy, it only applies when the result is traversed. *) +- +-val filter_map : ('a -> 'b option) -> 'a t -> 'b t +-(** Apply the function to every element; if [f x = None] then [x] is dropped; +- if [f x = Some y] then [y] is returned. +- This transformation is lazy, it only applies when the result is traversed. *) +- +-val flat_map : ('a -> 'b t) -> 'a t -> 'b t +-(** Map each element to a subsequence, then return each element of this +- sub-sequence in turn. +- This transformation is lazy, it only applies when the result is traversed. *) +- +-val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a +-(** Traverse the sequence from left to right, combining each element with the +- accumulator using the given function. +- The traversal happens immediately and will not terminate on infinite sequences. +- +- Also see {!List.fold_left} *) +- +-val iter : ('a -> unit) -> 'a t -> unit +-(** Iterate on the sequence, calling the (imperative) function on every element. +- The traversal happens immediately and will not terminate on infinite sequences. *) diff --git a/src/seq_alias.ml b/src/seq_alias.ml new file mode 100644 index 0000000..49d3313 @@ -100,26 +266,166 @@ index 0000000..8872dd5 @@ -0,0 +1,2 @@ + +include module type of Stdlib.Seq -diff --git a/src/seq.ml b/src/seq_redef.ml -similarity index 100% -rename from src/seq.ml -rename to src/seq_redef.ml -diff --git a/src/seq.mli b/src/seq_redef.mli -similarity index 99% -rename from src/seq.mli -rename to src/seq_redef.mli -index f33c19a..c22dff9 100644 ---- a/src/seq.mli +diff --git a/src/seq_redef.ml b/src/seq_redef.ml +new file mode 100644 +index 0000000..ccdbfde +--- /dev/null ++++ b/src/seq_redef.ml +@@ -0,0 +1,73 @@ ++(**************************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Simon Cruanes *) ++(* *) ++(* Copyright 2017 Institut National de Recherche en Informatique et *) ++(* en Automatique. *) ++(* *) ++(* All rights reserved. This file is distributed under the terms of *) ++(* the GNU Lesser General Public License version 2.1, with the *) ++(* special exception on linking described in the file LICENSE. *) ++(* *) ++(**************************************************************************) ++ ++(* Module [Seq]: functional iterators *) ++ ++type +'a node = ++ | Nil ++ | Cons of 'a * 'a t ++ ++and 'a t = unit -> 'a node ++ ++let empty () = Nil ++ ++let return x () = Cons (x, empty) ++ ++let rec map f seq () = match seq() with ++ | Nil -> Nil ++ | Cons (x, next) -> Cons (f x, map f next) ++ ++let rec filter_map f seq () = match seq() with ++ | Nil -> Nil ++ | Cons (x, next) -> ++ match f x with ++ | None -> filter_map f next () ++ | Some y -> Cons (y, filter_map f next) ++ ++let rec filter f seq () = match seq() with ++ | Nil -> Nil ++ | Cons (x, next) -> ++ if f x ++ then Cons (x, filter f next) ++ else filter f next () ++ ++let rec flat_map f seq () = match seq () with ++ | Nil -> Nil ++ | Cons (x, next) -> ++ flat_map_app f (f x) next () ++ ++(* this is [append seq (flat_map f tail)] *) ++and flat_map_app f seq tail () = match seq () with ++ | Nil -> flat_map f tail () ++ | Cons (x, next) -> ++ Cons (x, flat_map_app f next tail) ++ ++let fold_left f acc seq = ++ let rec aux f acc seq = match seq () with ++ | Nil -> acc ++ | Cons (x, next) -> ++ let acc = f acc x in ++ aux f acc next ++ in ++ aux f acc seq ++ ++let iter f seq = ++ let rec aux seq = match seq () with ++ | Nil -> () ++ | Cons (x, next) -> ++ f x; ++ aux next ++ in ++ aux seq +diff --git a/src/seq_redef.mli b/src/seq_redef.mli +new file mode 100644 +index 0000000..c22dff9 +--- /dev/null +++ b/src/seq_redef.mli -@@ -23,8 +23,6 @@ - them in a lazy fashion rather than upfront. - *) - --(** @since 4.07 *) -- - type 'a t = unit -> 'a node - (** The type of delayed lists containing elements of type ['a]. - Note that the concrete list node ['a node] is delayed under a closure, +@@ -0,0 +1,75 @@ ++(**************************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Simon Cruanes *) ++(* *) ++(* Copyright 2017 Institut National de Recherche en Informatique et *) ++(* en Automatique. *) ++(* *) ++(* All rights reserved. This file is distributed under the terms of *) ++(* the GNU Lesser General Public License version 2.1, with the *) ++(* special exception on linking described in the file LICENSE. *) ++(* *) ++(**************************************************************************) ++ ++(* Module [Seq]: functional iterators *) ++ ++(** {1 Functional Iterators} *) ++ ++(** The type ['a t] is a {b delayed list}, i.e. a list where some evaluation ++ is needed to access the next element. This makes it possible to build ++ infinite sequences, to build sequences as we traverse them, and to transform ++ them in a lazy fashion rather than upfront. ++*) ++ ++type 'a t = unit -> 'a node ++(** The type of delayed lists containing elements of type ['a]. ++ Note that the concrete list node ['a node] is delayed under a closure, ++ not a [lazy] block, which means it might be recomputed every time ++ we access it. *) ++ ++and +'a node = ++ | Nil ++ | Cons of 'a * 'a t ++(** A fully-evaluated list node, either empty or containing an element ++ and a delayed tail. *) ++ ++val empty : 'a t ++(** The empty sequence, containing no elements. *) ++ ++val return : 'a -> 'a t ++(** The singleton sequence containing only the given element. *) ++ ++val map : ('a -> 'b) -> 'a t -> 'b t ++(** [map f seq] returns a new sequence whose elements are the elements of ++ [seq], transformed by [f]. ++ This transformation is lazy, it only applies when the result is traversed. ++ ++ If [seq = [1;2;3]], then [map f seq = [f 1; f 2; f 3]]. *) ++ ++val filter : ('a -> bool) -> 'a t -> 'a t ++(** Remove from the sequence the elements that do not satisfy the ++ given predicate. ++ This transformation is lazy, it only applies when the result is traversed. *) ++ ++val filter_map : ('a -> 'b option) -> 'a t -> 'b t ++(** Apply the function to every element; if [f x = None] then [x] is dropped; ++ if [f x = Some y] then [y] is returned. ++ This transformation is lazy, it only applies when the result is traversed. *) ++ ++val flat_map : ('a -> 'b t) -> 'a t -> 'b t ++(** Map each element to a subsequence, then return each element of this ++ sub-sequence in turn. ++ This transformation is lazy, it only applies when the result is traversed. *) ++ ++val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a ++(** Traverse the sequence from left to right, combining each element with the ++ accumulator using the given function. ++ The traversal happens immediately and will not terminate on infinite sequences. ++ ++ Also see {!List.fold_left} *) ++ ++val iter : ('a -> unit) -> 'a t -> unit ++(** Iterate on the sequence, calling the (imperative) function on every element. ++ The traversal happens immediately and will not terminate on infinite sequences. *) -- 2.17.1 diff --git a/src_ext/patches/seq/0001-seq-0.2-for-jbuilder.patch b/src_ext/patches/seq/0001-seq-0.2-for-jbuilder.patch index d0fb2b5d732..56d97f3823e 100644 --- a/src_ext/patches/seq/0001-seq-0.2-for-jbuilder.patch +++ b/src_ext/patches/seq/0001-seq-0.2-for-jbuilder.patch @@ -4,20 +4,24 @@ Date: Thu, 19 Apr 2018 00:08:23 -0500 Subject: [PATCH] seq 0.2 for jbuilder --- - .gitignore | 2 ++ - Makefile | 11 ++++++++++- - select_version.ml | 14 ++++++++++++++ - seq.opam | 8 ++++---- - src/seq_alias.ml | 1 + - src/seq_alias.mli | 2 ++ - src/{seq.ml => seq_redef.ml} | 0 - src/{seq.mli => seq_redef.mli} | 2 -- - 8 files changed, 33 insertions(+), 7 deletions(-) + .gitignore | 2 ++ + Makefile | 11 ++++++- + select_version.ml | 14 +++++++++ + seq.opam | 8 ++--- + src/seq.ml | 73 -------------------------------------------- + src/seq.mli | 77 ----------------------------------------------- + src/seq_alias.ml | 1 + + src/seq_alias.mli | 2 ++ + src/seq_redef.ml | 73 ++++++++++++++++++++++++++++++++++++++++++++ + src/seq_redef.mli | 75 +++++++++++++++++++++++++++++++++++++++++++++ + 10 files changed, 181 insertions(+), 155 deletions(-) create mode 100644 select_version.ml + delete mode 100644 src/seq.ml + delete mode 100644 src/seq.mli create mode 100644 src/seq_alias.ml create mode 100644 src/seq_alias.mli - rename src/{seq.ml => seq_redef.ml} (100%) - rename src/{seq.mli => seq_redef.mli} (99%) + create mode 100644 src/seq_redef.ml + create mode 100644 src/seq_redef.mli diff --git a/.gitignore b/.gitignore index e35d885..487f91e 100644 @@ -96,6 +100,168 @@ index 8d3569c..d8f19cf 100644 +# because OCaml starts having a `Seq` module in the stdlib +available: [ocaml-version < "4.07.0"] +diff --git a/src/seq.ml b/src/seq.ml +deleted file mode 100644 +index ccdbfde..0000000 +--- a/src/seq.ml ++++ /dev/null +@@ -1,73 +0,0 @@ +-(**************************************************************************) +-(* *) +-(* OCaml *) +-(* *) +-(* Simon Cruanes *) +-(* *) +-(* Copyright 2017 Institut National de Recherche en Informatique et *) +-(* en Automatique. *) +-(* *) +-(* All rights reserved. This file is distributed under the terms of *) +-(* the GNU Lesser General Public License version 2.1, with the *) +-(* special exception on linking described in the file LICENSE. *) +-(* *) +-(**************************************************************************) +- +-(* Module [Seq]: functional iterators *) +- +-type +'a node = +- | Nil +- | Cons of 'a * 'a t +- +-and 'a t = unit -> 'a node +- +-let empty () = Nil +- +-let return x () = Cons (x, empty) +- +-let rec map f seq () = match seq() with +- | Nil -> Nil +- | Cons (x, next) -> Cons (f x, map f next) +- +-let rec filter_map f seq () = match seq() with +- | Nil -> Nil +- | Cons (x, next) -> +- match f x with +- | None -> filter_map f next () +- | Some y -> Cons (y, filter_map f next) +- +-let rec filter f seq () = match seq() with +- | Nil -> Nil +- | Cons (x, next) -> +- if f x +- then Cons (x, filter f next) +- else filter f next () +- +-let rec flat_map f seq () = match seq () with +- | Nil -> Nil +- | Cons (x, next) -> +- flat_map_app f (f x) next () +- +-(* this is [append seq (flat_map f tail)] *) +-and flat_map_app f seq tail () = match seq () with +- | Nil -> flat_map f tail () +- | Cons (x, next) -> +- Cons (x, flat_map_app f next tail) +- +-let fold_left f acc seq = +- let rec aux f acc seq = match seq () with +- | Nil -> acc +- | Cons (x, next) -> +- let acc = f acc x in +- aux f acc next +- in +- aux f acc seq +- +-let iter f seq = +- let rec aux seq = match seq () with +- | Nil -> () +- | Cons (x, next) -> +- f x; +- aux next +- in +- aux seq +diff --git a/src/seq.mli b/src/seq.mli +deleted file mode 100644 +index f33c19a..0000000 +--- a/src/seq.mli ++++ /dev/null +@@ -1,77 +0,0 @@ +-(**************************************************************************) +-(* *) +-(* OCaml *) +-(* *) +-(* Simon Cruanes *) +-(* *) +-(* Copyright 2017 Institut National de Recherche en Informatique et *) +-(* en Automatique. *) +-(* *) +-(* All rights reserved. This file is distributed under the terms of *) +-(* the GNU Lesser General Public License version 2.1, with the *) +-(* special exception on linking described in the file LICENSE. *) +-(* *) +-(**************************************************************************) +- +-(* Module [Seq]: functional iterators *) +- +-(** {1 Functional Iterators} *) +- +-(** The type ['a t] is a {b delayed list}, i.e. a list where some evaluation +- is needed to access the next element. This makes it possible to build +- infinite sequences, to build sequences as we traverse them, and to transform +- them in a lazy fashion rather than upfront. +-*) +- +-(** @since 4.07 *) +- +-type 'a t = unit -> 'a node +-(** The type of delayed lists containing elements of type ['a]. +- Note that the concrete list node ['a node] is delayed under a closure, +- not a [lazy] block, which means it might be recomputed every time +- we access it. *) +- +-and +'a node = +- | Nil +- | Cons of 'a * 'a t +-(** A fully-evaluated list node, either empty or containing an element +- and a delayed tail. *) +- +-val empty : 'a t +-(** The empty sequence, containing no elements. *) +- +-val return : 'a -> 'a t +-(** The singleton sequence containing only the given element. *) +- +-val map : ('a -> 'b) -> 'a t -> 'b t +-(** [map f seq] returns a new sequence whose elements are the elements of +- [seq], transformed by [f]. +- This transformation is lazy, it only applies when the result is traversed. +- +- If [seq = [1;2;3]], then [map f seq = [f 1; f 2; f 3]]. *) +- +-val filter : ('a -> bool) -> 'a t -> 'a t +-(** Remove from the sequence the elements that do not satisfy the +- given predicate. +- This transformation is lazy, it only applies when the result is traversed. *) +- +-val filter_map : ('a -> 'b option) -> 'a t -> 'b t +-(** Apply the function to every element; if [f x = None] then [x] is dropped; +- if [f x = Some y] then [y] is returned. +- This transformation is lazy, it only applies when the result is traversed. *) +- +-val flat_map : ('a -> 'b t) -> 'a t -> 'b t +-(** Map each element to a subsequence, then return each element of this +- sub-sequence in turn. +- This transformation is lazy, it only applies when the result is traversed. *) +- +-val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a +-(** Traverse the sequence from left to right, combining each element with the +- accumulator using the given function. +- The traversal happens immediately and will not terminate on infinite sequences. +- +- Also see {!List.fold_left} *) +- +-val iter : ('a -> unit) -> 'a t -> unit +-(** Iterate on the sequence, calling the (imperative) function on every element. +- The traversal happens immediately and will not terminate on infinite sequences. *) diff --git a/src/seq_alias.ml b/src/seq_alias.ml new file mode 100644 index 0000000..49d3313 @@ -111,26 +277,166 @@ index 0000000..8872dd5 @@ -0,0 +1,2 @@ + +include module type of Stdlib.Seq -diff --git a/src/seq.ml b/src/seq_redef.ml -similarity index 100% -rename from src/seq.ml -rename to src/seq_redef.ml -diff --git a/src/seq.mli b/src/seq_redef.mli -similarity index 99% -rename from src/seq.mli -rename to src/seq_redef.mli -index f33c19a..c22dff9 100644 ---- a/src/seq.mli +diff --git a/src/seq_redef.ml b/src/seq_redef.ml +new file mode 100644 +index 0000000..ccdbfde +--- /dev/null ++++ b/src/seq_redef.ml +@@ -0,0 +1,73 @@ ++(**************************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Simon Cruanes *) ++(* *) ++(* Copyright 2017 Institut National de Recherche en Informatique et *) ++(* en Automatique. *) ++(* *) ++(* All rights reserved. This file is distributed under the terms of *) ++(* the GNU Lesser General Public License version 2.1, with the *) ++(* special exception on linking described in the file LICENSE. *) ++(* *) ++(**************************************************************************) ++ ++(* Module [Seq]: functional iterators *) ++ ++type +'a node = ++ | Nil ++ | Cons of 'a * 'a t ++ ++and 'a t = unit -> 'a node ++ ++let empty () = Nil ++ ++let return x () = Cons (x, empty) ++ ++let rec map f seq () = match seq() with ++ | Nil -> Nil ++ | Cons (x, next) -> Cons (f x, map f next) ++ ++let rec filter_map f seq () = match seq() with ++ | Nil -> Nil ++ | Cons (x, next) -> ++ match f x with ++ | None -> filter_map f next () ++ | Some y -> Cons (y, filter_map f next) ++ ++let rec filter f seq () = match seq() with ++ | Nil -> Nil ++ | Cons (x, next) -> ++ if f x ++ then Cons (x, filter f next) ++ else filter f next () ++ ++let rec flat_map f seq () = match seq () with ++ | Nil -> Nil ++ | Cons (x, next) -> ++ flat_map_app f (f x) next () ++ ++(* this is [append seq (flat_map f tail)] *) ++and flat_map_app f seq tail () = match seq () with ++ | Nil -> flat_map f tail () ++ | Cons (x, next) -> ++ Cons (x, flat_map_app f next tail) ++ ++let fold_left f acc seq = ++ let rec aux f acc seq = match seq () with ++ | Nil -> acc ++ | Cons (x, next) -> ++ let acc = f acc x in ++ aux f acc next ++ in ++ aux f acc seq ++ ++let iter f seq = ++ let rec aux seq = match seq () with ++ | Nil -> () ++ | Cons (x, next) -> ++ f x; ++ aux next ++ in ++ aux seq +diff --git a/src/seq_redef.mli b/src/seq_redef.mli +new file mode 100644 +index 0000000..c22dff9 +--- /dev/null +++ b/src/seq_redef.mli -@@ -23,8 +23,6 @@ - them in a lazy fashion rather than upfront. - *) - --(** @since 4.07 *) -- - type 'a t = unit -> 'a node - (** The type of delayed lists containing elements of type ['a]. - Note that the concrete list node ['a node] is delayed under a closure, +@@ -0,0 +1,75 @@ ++(**************************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Simon Cruanes *) ++(* *) ++(* Copyright 2017 Institut National de Recherche en Informatique et *) ++(* en Automatique. *) ++(* *) ++(* All rights reserved. This file is distributed under the terms of *) ++(* the GNU Lesser General Public License version 2.1, with the *) ++(* special exception on linking described in the file LICENSE. *) ++(* *) ++(**************************************************************************) ++ ++(* Module [Seq]: functional iterators *) ++ ++(** {1 Functional Iterators} *) ++ ++(** The type ['a t] is a {b delayed list}, i.e. a list where some evaluation ++ is needed to access the next element. This makes it possible to build ++ infinite sequences, to build sequences as we traverse them, and to transform ++ them in a lazy fashion rather than upfront. ++*) ++ ++type 'a t = unit -> 'a node ++(** The type of delayed lists containing elements of type ['a]. ++ Note that the concrete list node ['a node] is delayed under a closure, ++ not a [lazy] block, which means it might be recomputed every time ++ we access it. *) ++ ++and +'a node = ++ | Nil ++ | Cons of 'a * 'a t ++(** A fully-evaluated list node, either empty or containing an element ++ and a delayed tail. *) ++ ++val empty : 'a t ++(** The empty sequence, containing no elements. *) ++ ++val return : 'a -> 'a t ++(** The singleton sequence containing only the given element. *) ++ ++val map : ('a -> 'b) -> 'a t -> 'b t ++(** [map f seq] returns a new sequence whose elements are the elements of ++ [seq], transformed by [f]. ++ This transformation is lazy, it only applies when the result is traversed. ++ ++ If [seq = [1;2;3]], then [map f seq = [f 1; f 2; f 3]]. *) ++ ++val filter : ('a -> bool) -> 'a t -> 'a t ++(** Remove from the sequence the elements that do not satisfy the ++ given predicate. ++ This transformation is lazy, it only applies when the result is traversed. *) ++ ++val filter_map : ('a -> 'b option) -> 'a t -> 'b t ++(** Apply the function to every element; if [f x = None] then [x] is dropped; ++ if [f x = Some y] then [y] is returned. ++ This transformation is lazy, it only applies when the result is traversed. *) ++ ++val flat_map : ('a -> 'b t) -> 'a t -> 'b t ++(** Map each element to a subsequence, then return each element of this ++ sub-sequence in turn. ++ This transformation is lazy, it only applies when the result is traversed. *) ++ ++val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a ++(** Traverse the sequence from left to right, combining each element with the ++ accumulator using the given function. ++ The traversal happens immediately and will not terminate on infinite sequences. ++ ++ Also see {!List.fold_left} *) ++ ++val iter : ('a -> unit) -> 'a t -> unit ++(** Iterate on the sequence, calling the (imperative) function on every element. ++ The traversal happens immediately and will not terminate on infinite sequences. *) -- 2.17.1