public
Description: Fork of OCaml compiler
Homepage: http://caml.inria.fr/ocaml/index.en.html
Clone URL: git://github.com/thelema/ocaml-community.git
Use Yoric's newest version of enum module (+ lots of fixes to compilation 
dependencies) + rewritten List.(--)
thelema (author)
Sun May 18 09:14:13 -0700 2008
commit  3abcef43d4559a6c5305c2597c56e0d7e53f6ce9
tree    8de702a2b81b9bf2c1810e6da2e353cd201f9720
parent  4c1fde6204047ee327a61c527925f26d00d837a4
...
 
1
2
3
...
7
8
9
 
10
11
12
13
14
 
 
15
16
17
18
 
 
19
20
21
...
32
33
34
35
36
37
 
 
 
38
39
 
40
41
42
...
44
45
46
47
48
 
 
49
50
51
52
53
54
 
 
55
56
57
...
66
67
68
69
70
 
 
71
72
73
...
80
81
82
83
84
 
 
85
86
87
88
 
 
 
 
89
90
91
...
100
101
102
103
104
 
 
105
106
107
108
109
110
 
 
111
112
...
1
2
3
4
...
8
9
10
11
12
13
14
 
 
15
16
17
18
 
 
19
20
21
22
23
...
34
35
36
 
 
 
37
38
39
40
 
41
42
43
44
...
46
47
48
 
 
49
50
51
52
53
54
 
 
55
56
57
58
59
...
68
69
70
 
 
71
72
73
74
75
...
82
83
84
 
 
85
86
87
88
89
90
91
92
93
94
95
96
97
...
106
107
108
 
 
109
110
111
112
113
114
 
 
115
116
117
118
0
@@ -1,3 +1,4 @@
0
+array.cmi: enum.cmi
0
 camlinternalMod.cmi: obj.cmi
0
 camlinternalOO.cmi: obj.cmi
0
 format.cmi: buffer.cmi
0
@@ -7,15 +8,16 @@ oo.cmi: camlinternalOO.cmi
0
 parsing.cmi: obj.cmi lexing.cmi
0
 printf.cmi: obj.cmi buffer.cmi
0
 random.cmi: nativeint.cmi int64.cmi int32.cmi
0
+string.cmi: enum.cmi
0
 weak.cmi: hashtbl.cmi
0
 arg.cmo: sys.cmi string.cmi printf.cmi list.cmi buffer.cmi array.cmi arg.cmi
0
 arg.cmx: sys.cmx string.cmx printf.cmx list.cmx buffer.cmx array.cmx arg.cmi
0
-array.cmo: array.cmi
0
-array.cmx: array.cmi
0
+array.cmo: enum.cmi bitSet.cmi array.cmi
0
+array.cmx: enum.cmx bitSet.cmx array.cmi
0
 arrayLabels.cmo: array.cmi arrayLabels.cmi
0
 arrayLabels.cmx: array.cmx arrayLabels.cmi
0
-bitSet.cmo: bitSet.cmi
0
-bitSet.cmx: bitSet.cmi
0
+bitSet.cmo: bitSet.cmi
0
+bitSet.cmx: bitSet.cmi
0
 buffer.cmo: sys.cmi string.cmi buffer.cmi
0
 buffer.cmx: sys.cmx string.cmx buffer.cmi
0
 callback.cmo: obj.cmi callback.cmi
0
@@ -32,11 +34,11 @@ complex.cmo: complex.cmi
0
 complex.cmx: complex.cmi
0
 digest.cmo: string.cmi printf.cmi digest.cmi
0
 digest.cmx: string.cmx printf.cmx digest.cmi
0
-enum.cmo: enum.cmi
0
-enum.cmx: enum.cmi
0
-filename.cmo: sys.cmi string.cmi random.cmi printf.cmi buffer.cmi \
0
+enum.cmo: ref.cmi queue.cmi obj.cmi lazy.cmi char.cmi enum.cmi
0
+enum.cmx: ref.cmx queue.cmx obj.cmx lazy.cmx char.cmx enum.cmi
0
+filename.cmo: sys.cmi string.cmi random.cmi printf.cmi list.cmi buffer.cmi \
0
     filename.cmi
0
-filename.cmx: sys.cmx string.cmx random.cmx printf.cmx buffer.cmx \
0
+filename.cmx: sys.cmx string.cmx random.cmx printf.cmx list.cmx buffer.cmx \
0
     filename.cmi
0
 format.cmo: string.cmi printf.cmi obj.cmi list.cmi buffer.cmi format.cmi
0
 format.cmx: string.cmx printf.cmx obj.cmx list.cmx buffer.cmx format.cmi
0
@@ -44,14 +46,14 @@ gc.cmo: sys.cmi printf.cmi gc.cmi
0
 gc.cmx: sys.cmx printf.cmx gc.cmi
0
 genlex.cmo: string.cmi stream.cmi list.cmi hashtbl.cmi char.cmi genlex.cmi
0
 genlex.cmx: string.cmx stream.cmx list.cmx hashtbl.cmx char.cmx genlex.cmi
0
-hashtbl.cmo: sys.cmi array.cmi hashtbl.cmi
0
-hashtbl.cmx: sys.cmx array.cmx hashtbl.cmi
0
+hashtbl.cmo: sys.cmi obj.cmi buffer.cmi array.cmi hashtbl.cmi
0
+hashtbl.cmx: sys.cmx obj.cmx buffer.cmx array.cmx hashtbl.cmi
0
 int32.cmo: pervasives.cmi int32.cmi
0
 int32.cmx: pervasives.cmx int32.cmi
0
 int64.cmo: pervasives.cmi int64.cmi
0
 int64.cmx: pervasives.cmx int64.cmi
0
-lazy.cmo: obj.cmi lazy.cmi
0
-lazy.cmx: obj.cmx lazy.cmi
0
+lazy.cmo: lazy.cmi
0
+lazy.cmx: lazy.cmi
0
 lexing.cmo: sys.cmi string.cmi array.cmi lexing.cmi
0
 lexing.cmx: sys.cmx string.cmx array.cmx lexing.cmi
0
 list.cmo: list.cmi
0
@@ -66,8 +68,8 @@ moreLabels.cmo: set.cmi map.cmi hashtbl.cmi moreLabels.cmi
0
 moreLabels.cmx: set.cmx map.cmx hashtbl.cmx moreLabels.cmi
0
 nativeint.cmo: sys.cmi pervasives.cmi nativeint.cmi
0
 nativeint.cmx: sys.cmx pervasives.cmx nativeint.cmi
0
-obj.cmo: marshal.cmi obj.cmi
0
-obj.cmx: marshal.cmx obj.cmi
0
+obj.cmo: string.cmi marshal.cmi list.cmi obj.cmi
0
+obj.cmx: string.cmx marshal.cmx list.cmx obj.cmi
0
 oo.cmo: camlinternalOO.cmi oo.cmi
0
 oo.cmx: camlinternalOO.cmx oo.cmi
0
 parsing.cmo: obj.cmi lexing.cmi array.cmi parsing.cmi
0
@@ -80,12 +82,16 @@ printf.cmo: string.cmi obj.cmi list.cmi char.cmi buffer.cmi array.cmi \
0
     printf.cmi
0
 printf.cmx: string.cmx obj.cmx list.cmx char.cmx buffer.cmx array.cmx \
0
     printf.cmi
0
-queue.cmo: obj.cmi queue.cmi
0
-queue.cmx: obj.cmx queue.cmi
0
+queue.cmo: queue.cmi
0
+queue.cmx: queue.cmi
0
 random.cmo: string.cmi pervasives.cmi nativeint.cmi int64.cmi int32.cmi \
0
     digest.cmi char.cmi array.cmi random.cmi
0
 random.cmx: string.cmx pervasives.cmx nativeint.cmx int64.cmx int32.cmx \
0
     digest.cmx char.cmx array.cmx random.cmi
0
+ref.cmo: ref.cmi
0
+ref.cmx: ref.cmi
0
+rope1.cmo: string.cmi array.cmi
0
+rope1.cmx: string.cmx array.cmx
0
 scanf.cmo: string.cmi printf.cmi obj.cmi list.cmi hashtbl.cmi buffer.cmi \
0
     array.cmi scanf.cmi
0
 scanf.cmx: string.cmx printf.cmx obj.cmx list.cmx hashtbl.cmx buffer.cmx \
0
@@ -100,13 +106,13 @@ stdLabels.cmo: stringLabels.cmi listLabels.cmi arrayLabels.cmi stdLabels.cmi
0
 stdLabels.cmx: stringLabels.cmx listLabels.cmx arrayLabels.cmx stdLabels.cmi
0
 stream.cmo: string.cmi obj.cmi list.cmi stream.cmi
0
 stream.cmx: string.cmx obj.cmx list.cmx stream.cmi
0
-string.cmo: pervasives.cmi list.cmi char.cmi string.cmi
0
-string.cmx: pervasives.cmx list.cmx char.cmx string.cmi
0
+string.cmo: pervasives.cmi list.cmi enum.cmi char.cmi string.cmi
0
+string.cmx: pervasives.cmx list.cmx enum.cmx char.cmx string.cmi
0
 stringLabels.cmo: string.cmi stringLabels.cmi
0
 stringLabels.cmx: string.cmx stringLabels.cmi
0
 sys.cmo: sys.cmi
0
 sys.cmx: sys.cmi
0
-typestruct.cmo: typestruct.cmi
0
-typestruct.cmx: typestruct.cmi
0
+typestruct.cmo: typestruct.cmi
0
+typestruct.cmx: typestruct.cmi
0
 weak.cmo: sys.cmi obj.cmi hashtbl.cmi array.cmi weak.cmi
0
 weak.cmx: sys.cmx obj.cmx hashtbl.cmx array.cmx weak.cmi
...
25
26
27
28
 
 
29
30
31
32
 
33
34
35
36
37
38
 
39
40
41
...
25
26
27
 
28
29
30
31
32
 
33
34
35
36
37
38
 
39
40
41
42
0
@@ -25,17 +25,18 @@ OPTCOMPFLAGS=-warn-error A -nostdlib -g
0
 CAMLDEP=../boot/ocamlrun ../tools/ocamldep
0
 
0
 OBJS=pervasives.cmo $(OTHERS)
0
-OTHERS=enum.cmo bitSet.cmo array.cmo list.cmo char.cmo string.cmo sys.cmo \
0
+OTHERS=lazy.cmo ref.cmo char.cmo queue.cmo enum.cmo bitSet.cmo \
0
+ array.cmo list.cmo string.cmo sys.cmo \
0
   sort.cmo marshal.cmo obj.cmo buffer.cmo hashtbl.cmo \
0
   int32.cmo int64.cmo nativeint.cmo \
0
   lexing.cmo parsing.cmo \
0
- set.cmo map.cmo stack.cmo queue.cmo stream.cmo \
0
+ set.cmo map.cmo stack.cmo stream.cmo \
0
   printf.cmo format.cmo scanf.cmo \
0
   arg.cmo printexc.cmo gc.cmo \
0
   digest.cmo random.cmo callback.cmo \
0
   camlinternalOO.cmo oo.cmo camlinternalMod.cmo \
0
   genlex.cmo weak.cmo typestruct.cmo \
0
- lazy.cmo filename.cmo complex.cmo \
0
+ filename.cmo complex.cmo \
0
   arrayLabels.cmo listLabels.cmo stringLabels.cmo moreLabels.cmo stdLabels.cmo
0
 
0
 all: stdlib.cma std_exit.cmo camlheader camlheader_ur
...
6
7
8
 
9
10
11
...
13
14
15
 
16
17
18
...
6
7
8
9
10
11
12
...
14
15
16
17
18
19
20
0
@@ -6,6 +6,7 @@ STDLIB_MODULES=\
0
   arg \
0
   array \
0
   arrayLabels \
0
+ bitSet \
0
   buffer \
0
   callback \
0
   camlinternalMod \
0
@@ -13,6 +14,7 @@ STDLIB_MODULES=\
0
   char \
0
   complex \
0
   digest \
0
+ enum \
0
   filename \
0
   format \
0
   gc \
...
1
2
3
 
4
5
6
...
18
19
20
 
21
22
23
...
28
29
30
31
32
33
34
35
...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 
 
55
56
57
58
59
60
61
62
 
 
 
 
 
 
63
 
64
65
66
...
106
107
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
110
111
...
114
115
116
117
 
 
 
 
 
 
 
118
119
 
120
121
122
...
127
128
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
131
132
...
377
378
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
...
19
20
21
22
23
24
25
...
30
31
32
 
 
33
34
35
...
38
39
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
42
43
 
 
 
 
 
 
 
44
45
46
47
48
49
50
51
52
53
54
...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
150
151
152
 
153
154
155
156
157
158
159
160
161
162
163
164
165
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
0
@@ -1,6 +1,7 @@
0
 (*
0
  * Enum - Enumeration over abstract collection of elements.
0
  * Copyright (C) 2003 Nicolas Cannasse
0
+ * 2008 David Teller (contributor)
0
  *
0
  * This library is free software; you can redistribute it and/or
0
  * modify it under the terms of the GNU Lesser General Public
0
@@ -18,6 +19,7 @@
0
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0
  *)
0
 
0
+(** {6 Representation} *)
0
 type 'a t = {
0
   mutable count : unit -> int;
0
   mutable next : unit -> 'a;
0
@@ -28,8 +30,6 @@ type 'a t = {
0
 (* raised by 'next' functions, should NOT go outside the API *)
0
 exception No_more_elements
0
 
0
-let _dummy () = assert false
0
-
0
 let make ~next ~count ~clone =
0
   {
0
     count = count;
0
@@ -38,29 +38,17 @@ let make ~next ~count ~clone =
0
     fast = true;
0
   }
0
 
0
-let rec init n f =
0
- if n < 0 then invalid_arg "Enum.init";
0
- let count = ref n in
0
- {
0
- count = (fun () -> !count);
0
- next = (fun () ->
0
- match !count with
0
- | 0 -> raise No_more_elements
0
- | _ ->
0
- decr count;
0
- f (n - 1 - !count));
0
- clone = (fun () -> init !count f);
0
- fast = true;
0
- }
0
+(** {6 Internal utilities}*)
0
+let _dummy () = assert false
0
 
0
-let rec empty () =
0
- {
0
- count = (fun () -> 0);
0
- next = (fun () -> raise No_more_elements);
0
- clone = (fun () -> empty());
0
- fast = true;
0
- }
0
+(* raised by 'count' functions, may go outside the API *)
0
+exception Infinite_enum
0
+
0
+let return_no_more_elements () = raise No_more_elements
0
+let return_no_more_count () = 0
0
+let return_infinite_count () = raise Infinite_enum
0
 
0
+(* Inlined from ExtList to avoid circular dependencies. *)
0
 type 'a _mut_list = {
0
   hd : 'a;
0
   mutable tl : 'a _mut_list;
0
@@ -106,6 +94,54 @@ let force t =
0
   t.count <- tc.count;
0
   t.fast <- true
0
 
0
+(* Inlined from {!LazyList}.
0
+
0
+ This lazy list permits cloning enumerations constructed with {!from}
0
+ without having to actually force them.*)
0
+module MicroLazyList = struct
0
+ type 'a ll_t = ('a node_t) Lazy.t
0
+ and 'a node_t =
0
+ | Nil
0
+ | Cons of 'a * 'a ll_t
0
+
0
+ let nil = lazy Nil
0
+
0
+ let enum l =
0
+ let rec aux (l:'a ll_t) : 'a t=
0
+ let reference = ref l in
0
+ let e = make
0
+ ~next:(fun () -> match Lazy.force !reference with
0
+ | Cons(x,t) -> reference := t; x
0
+ | _ -> raise No_more_elements )
0
+ ~count:_dummy
0
+ ~clone:(fun () -> aux !reference)
0
+ in e.count <- (fun () -> force e; e.count());
0
+ e
0
+ in aux l
0
+
0
+ let from f =
0
+ let rec aux () =
0
+ lazy (
0
+ let item = try Some (f ())
0
+ with No_more_elements -> None
0
+ in match item with
0
+ | Some x -> Cons (x, aux () )
0
+ | _ -> Nil
0
+ )
0
+ in
0
+ aux ()
0
+
0
+
0
+end
0
+
0
+let rec empty () =
0
+ {
0
+ count = return_no_more_count;
0
+ next = return_no_more_elements;
0
+ clone = (fun () -> empty());
0
+ fast = true;
0
+ }
0
+
0
 let from f =
0
   let e = {
0
     next = f;
0
@@ -114,9 +150,16 @@ let from f =
0
     fast = false;
0
   } in
0
   e.count <- (fun () -> force e; e.count());
0
- e.clone <- (fun () -> force e; e.clone());
0
+ e.clone <- (fun () ->
0
+ let e' = MicroLazyList.enum(MicroLazyList.from f) in
0
+ e.next <- e'.next;
0
+ e.clone<- e'.clone;
0
+ e.count<- e'.count;
0
+ e.fast <- false; e.fast <- false;
0
+ e.clone () );
0
   e
0
 
0
+
0
 let from2 next clone =
0
   let e = {
0
     next = next;
0
@@ -127,6 +170,20 @@ let from2 next clone =
0
   e.count <- (fun () -> force e; e.count());
0
   e
0
 
0
+let init n f = (*Experimental fix for init*)
0
+ if n < 0 then invalid_arg "Enum.init";
0
+ let count = ref n in
0
+ let f' () =
0
+ match !count with
0
+ | 0 -> raise No_more_elements
0
+ | _ -> decr count;
0
+ f ( n - 1 - !count)
0
+ in let e = from f' in
0
+ e.fast <- true;
0
+ e.count <- (fun () -> !count);
0
+ e
0
+
0
+
0
 let get t =
0
   try
0
     Some (t.next())
0
@@ -377,3 +434,174 @@ let rec concat t =
0
   in
0
   concat_ref := concat_next;
0
   from2 (fun () -> !concat_ref ()) (fun () -> concat (t.clone()))
0
+
0
+
0
+let singleton x =
0
+ init 1 (fun _ -> x)
0
+
0
+(* break recursive dependency loop *)
0
+module Array = struct
0
+ external get: 'a array -> int -> 'a = "%array_safe_get"
0
+ external unsafe_get: 'a array -> int -> 'a = "%array_unsafe_get"
0
+ external unsafe_set: 'a array -> int -> 'a -> unit = "%array_unsafe_set"
0
+ external create: int -> 'a -> 'a array = "caml_make_vect"
0
+
0
+ let init l ~f =
0
+ if l = 0 then [||] else
0
+ let res = create l (f 0) in
0
+ for i = 1 to pred l do
0
+ unsafe_set res i (f i)
0
+ done;
0
+ res
0
+end
0
+
0
+let switchn n f e =
0
+ let queues = Array.init n ~f:(fun _ -> Queue.create ()) in
0
+ let gen i () = (*Generate the next value for the i^th enum*)
0
+ let my_queue = Array.unsafe_get queues i in
0
+ if Queue.is_empty my_queue then (*Need to fetch next*)
0
+ let rec aux () = (*Keep fetching until an appropriate
0
+ item has been found*)
0
+ let next_item = e.next() in
0
+ let position = f next_item in
0
+ if i = position then next_item
0
+ else
0
+ (
0
+ Queue.push next_item (Array.get queues position);
0
+ aux ()
0
+ )
0
+ in aux ()
0
+ else Queue.take my_queue
0
+ in Array.init ~f:(fun i -> from (gen i)) n
0
+
0
+let switch f e =
0
+ let a = switchn 2 (fun x -> if f x then 0 else 1) e in
0
+ (a.(0), a.(1))
0
+
0
+let seq init f cond =
0
+ let acc = ref init in
0
+ let aux () = if cond !acc then Ref.pre acc f
0
+ else raise No_more_elements
0
+ in from aux
0
+
0
+let repeat ?times x = match times with
0
+ | None ->
0
+ let rec aux =
0
+ {
0
+ count = return_infinite_count;
0
+ next = (fun () -> x);
0
+ clone = (fun () -> aux);
0
+ fast = true;
0
+ } in aux
0
+ | Some n ->
0
+ init n (fun _ -> x)
0
+
0
+let cycle ?times x =
0
+ let enum =
0
+ match times with
0
+ | None -> from (fun () -> clone x)
0
+ | Some n -> init n (fun _ -> clone x)
0
+ in concat enum
0
+
0
+let range ?until x =
0
+ let cond = match until with
0
+ | None -> ( fun _ -> true )
0
+ | Some n -> ( fun m -> m <= n )
0
+ in seq x ( ( + ) 1 ) cond
0
+
0
+
0
+let drop n e =
0
+ for i = 1 to n do
0
+ junk e
0
+ done
0
+
0
+let close e =
0
+ e.next <- return_no_more_elements;
0
+ e.count<- return_no_more_count;
0
+ e.clone<- empty
0
+
0
+let before_do t f =
0
+ let rec make t =
0
+ let fnext = t.next in
0
+ let fclone = t.clone in
0
+ let next_called = ref false in
0
+ t.next <- (fun () -> f();
0
+ next_called := true;
0
+ t.clone <- fclone;
0
+ t.next <- fnext ;
0
+ fnext () );
0
+
0
+ t.clone <- (fun () ->
0
+ let tc = fclone() in
0
+ if not !next_called then make tc;
0
+ tc);
0
+ in
0
+ make t
0
+
0
+let drop_while p e =
0
+ let rec aux () =
0
+ match peek e with
0
+ | None -> e
0
+ | Some x when p x -> junk e; aux ()
0
+ | _ -> e
0
+ in
0
+ before_do e aux; e
0
+
0
+let take_while f t =
0
+ let rec next () =
0
+ let x = t.next () in
0
+ if f x then x
0
+ else raise No_more_elements
0
+ in from next
0
+
0
+
0
+let ( -- ) x y = range x ~until:y
0
+
0
+let ( --- ) x y = if x > y then y -- x
0
+ else x -- y
0
+
0
+let ( ~~ ) a b = map Char.chr (range (Char.code a) ~until:(Char.code b))
0
+
0
+
0
+let from_while f =
0
+ from(fun () -> match f () with
0
+ | None -> raise No_more_elements
0
+ | Some x -> x )
0
+
0
+
0
+let from_loop data next =
0
+ let r = ref data in
0
+ from(fun () -> let (a,b) = next !r in
0
+ r := b;
0
+ a)
0
+
0
+let seq_hide data next =
0
+ from_loop data (fun data -> match next data with
0
+ | None -> raise No_more_elements
0
+ | Some x -> x )
0
+
0
+let slazy f =
0
+ let constructor = lazy (f ()) in
0
+ make ~next: (fun () -> (Lazy.force constructor).next ())
0
+ ~count: (fun () -> (Lazy.force constructor).count())
0
+ ~clone: (fun () -> (Lazy.force constructor).clone())
0
+
0
+let lsing f =
0
+ init 1 (fun _ -> f ())
0
+
0
+
0
+
0
+let lcons f e = append (lsing f) e
0
+let lapp f e = append (slazy f) e
0
+
0
+let ising = singleton
0
+let icons f e = append (ising f) e
0
+let iapp = append
0
+
0
+
0
+
0
+module ExceptionLess = struct
0
+ let find f e =
0
+ try Some (find f e)
0
+ with Not_found -> None
0
+end
...
1
2
3
 
4
5
6
...
17
18
19
20
21
22
23
...
106
107
108
 
 
 
 
 
 
 
 
 
 
 
109
110
111
...
154
155
156
 
 
 
 
157
158
159
...
163
164
165
166
 
 
167
168
169
...
176
177
178
179
180
 
 
181
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
184
185
186
 
 
 
 
 
 
 
 
 
 
 
 
 
187
188
189
...
199
200
201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
...
18
19
20
 
21
22
23
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
...
165
166
167
168
169
170
171
172
173
174
...
178
179
180
 
181
182
183
184
185
...
192
193
194
 
 
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
0
@@ -1,6 +1,7 @@
0
 (*
0
  * Enum - enumeration over abstract collection of elements.
0
  * Copyright (C) 2003 Nicolas Cannasse
0
+ * 2008 David Teller (contributor)
0
  *
0
  * This library is free software; you can redistribute it and/or
0
  * modify it under the terms of the GNU Lesser General Public
0
@@ -17,7 +18,6 @@
0
  * License along with this library; if not, write to the Free Software
0
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0
  *)
0
-
0
 (** Enumeration over abstract collection of elements.
0
 
0
  Enumerations are entirely functional and most of the operations do not
0
@@ -106,6 +106,17 @@ val force : 'a t -> unit
0
   of enumerated elements is constructed and [e] will now enumerate over
0
   that data structure. *)
0
 
0
+val drop : int -> 'a t -> unit
0
+(** [drop n e] removes the first [n] element from the enumeration, if any. *)
0
+
0
+val take_while : ('a -> bool) -> 'a t -> 'a t
0
+ (** [take_while f e] produces a new enumeration in which only remain
0
+ the first few elements [x] of [e] such that [f x] *)
0
+
0
+val drop_while : ('a -> bool) -> 'a t -> 'a t
0
+ (** [drop_while p e] produces a new enumeration in which only
0
+ all the first elements such that [f e] have been junked.*)
0
+
0
 (** {6 Lazy constructors}
0
 
0
  These functions are lazy which means that they will create a new modified
0
@@ -154,6 +165,10 @@ exception No_more_elements
0
   other function specified in the interface.
0
 *)
0
 
0
+exception Infinite_enum
0
+(** As a convenience for debugging, this exception {i may} be raised by
0
+ the [count] function of [make] when attempting to count an infinite enum.*)
0
+
0
 val empty : unit -> 'a t
0
 (** The empty enumeration : contains no element *)
0
 
0
@@ -163,7 +178,8 @@ val make : next:(unit -> 'a) -> count:(unit -> int) -> clone:(unit -> 'a t) -> '
0
   enumeration or raise [No_more_elements] if the underlying data structure
0
   does not have any more elements to enumerate.}
0
   {li the [count] function {i shall} return the actual number of remaining
0
- elements in the enumeration.}
0
+ elements in the enumeration or {i may} raise [Infinite_enum] if it is known
0
+ that the enumeration is infinite.}
0
   {li the [clone] function {i shall} create a clone of the enumeration
0
   such as operations on the original enumeration will not affect the
0
   clone. }}
0
@@ -176,14 +192,55 @@ val from : (unit -> 'a) -> 'a t
0
 (** [from next] creates an enumeration from the [next] function.
0
  [next] {i shall} return the next element of the enumeration or raise
0
  [No_more_elements] when no more elements can be enumerated. Since the
0
- enumeration definition is incomplete, a call to [clone] or [count] will
0
- result in a call to [force] that will enumerate all elements in order to
0
+ enumeration definition is incomplete, a call to [count] will result in
0
+ a call to [force] that will enumerate all elements in order to
0
  return a correct value. *)
0
 
0
+val from_while : (unit -> 'a option) -> 'a t
0
+(** [from_while next] creates an enumeration from the [next] function.
0
+ [next] {i shall} return [Some x] where [x] is the next element of the
0
+ enumeration or [None] when no more elements can be enumerated. Since the
0
+ enumeration definition is incomplete, a call to [clone] or [count] will
0
+ result in a call to [force] that will enumerate all elements in order to
0
+ return a correct value. *)
0
+
0
+val from_loop: 'b -> ('b -> ('a * 'b)) -> 'a t
0
+ (**[from_loop data next] creates a (possibly infinite) enumeration from
0
+ the successive results of applying [next] to [data], then to the
0
+ result, etc. The list ends whenever the function raises
0
+ {!LazyList.No_more_elements}*)
0
+
0
+val seq : 'a -> ('a -> 'a) -> ('a -> bool) -> 'a t
0
+ (** [seq init step cond] creates a sequence of data, which starts
0
+ from [init], extends by [step], until the condition [cond]
0
+ fails. E.g. [seq 1 ((+) 1) ((>) 100)] returns [1, 2, ... 99]. If [cond
0
+ init] is false, the result is empty. *)
0
+
0
+
0
+val seq_hide: 'b -> ('b -> ('a * 'b) option) -> 'a t
0
+ (**More powerful version of [seq], with the ability of hiding data.
0
+
0
+ [seq_hide data next] creates a (possibly infinite) enumeration from
0
+ the successive results of applying [next] to [data], then to the
0
+ result, etc. The list ends whenever the function returns [None]*)
0
+
0
 val init : int -> (int -> 'a) -> 'a t
0
 (** [init n f] creates a new enumeration over elements
0
   [f 0, f 1, ..., f (n-1)] *)
0
 
0
+val singleton : 'a -> 'a t
0
+(** Create an enumeration consisting in exactly one element.*)
0
+
0
+val repeat : ?times:int -> 'a -> 'a t
0
+ (** [repeat ~times:n x] creates a enum sequence filled with [n] times of
0
+ [x]. It return infinite enum when [~times] is absent. It returns empty
0
+ enum when [times <= 0] *)
0
+
0
+val cycle : ?times:int -> 'a t -> 'a t
0
+ (** [cycle] is similar to [repeat], except that the content to fill is a
0
+ subenum rather than a single element. Note that [times] represents the
0
+ times of repeating not the length of enum. *)
0
+
0
 (** {6 Counting} *)
0
 
0
 val count : 'a t -> int
0
@@ -199,3 +256,72 @@ val fast_count : 'a t -> bool
0
     function that will give an hint about [count] implementation. Basically, if
0
     the enumeration has been created with [make] or [init] or if [force] has
0
     been called on it, then [fast_count] will return true. *)
0
+
0
+
0
+(**
0
+ {6 Utilities }
0
+*)
0
+val range : ?until:int -> int -> int t
0
+(** [range p until:q] creates an enumeration of integers [[p, p+1, ..., q]].
0
+ If [until] is omitted, the enumeration is not bounded. Behaviour is
0
+ not-specified once [max_int] has been reached.*)
0
+
0
+val ( -- ) : int -> int -> int t
0
+(** As [range], without the label.
0
+
0
+ [5 -- 10] is the enumeration 5,6,7,8,9,10.
0
+ [10 -- 5] is the empty enumeration*)
0
+
0
+val ( --- ) : int -> int -> int t
0
+(** As [--], but accepts enumerations in reverse order.
0
+
0
+ [5 --- 10] is the enumeration 5,6,7,8,9,10.
0
+ [10 --- 5] is the enumeration 10,9,8,7,6,5.*)
0
+
0
+val ( ~~ ) : char -> char -> char t
0
+(** As ( -- ), but for characters.*)
0
+
0
+
0
+val switchn: int -> ('a -> int) -> 'a t -> 'a t array
0
+ (** [switchn] is the array version of [switch]. [switch n f fl] split [fl] to an array of [n] enums, [f] is
0
+ applied to each element of [fl] to decide the id of its destination
0
+ enum. *)
0
+
0
+val switch : ('a -> bool) -> 'a t -> 'a t * 'a t
0
+ (** [switch test enum] split [enum] into two enums, where the first enum have
0
+ all the elements satisfying [test], the second enum is opposite. The
0
+ order of elements in the source enum is preserved. *)
0
+
0
+
0
+module ExceptionLess : sig
0
+ val find : ('a -> bool) -> 'a t -> 'a option
0
+ (** [find f e] returns [Some x] where [x] is the first element [x] of [e]
0
+ such that [f x] returns [true], consuming the enumeration up to and
0
+ including the found element, or [None] if no such element exists
0
+ in the enumeration, consuming the whole enumeration in the search.
0
+
0
+ Since [find] consumes a prefix of the enumeration, it can be used several
0
+ times on the same enumeration to find the next element. *)
0
+
0
+
0
+end
0
+
0
+(**/**)
0
+
0
+(** {6 For system use only, not for the casual user}
0
+
0
+ For compatibility with [Stream]
0
+*)
0
+
0
+val iapp : 'a t -> 'a t -> 'a t
0
+val icons : 'a -> 'a t -> 'a t
0
+val ising : 'a -> 'a t
0
+
0
+val lapp : (unit -> 'a t) -> 'a t -> 'a t
0
+val lcons : (unit -> 'a) -> 'a t -> 'a t
0
+val lsing : (unit -> 'a) -> 'a t
0
+
0
+val slazy : (unit -> 'a t) -> 'a t
0
+
0
+
0
+(**/**)
...
44
45
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
48
49
...
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
0
@@ -44,6 +44,35 @@
0
    let the compiler implement the special typing and compilation
0
    rules for the [lazy] keyword.
0
 *)
0
+module Obj = struct (* break module recursion *)
0
+ type t
0
+ external re