(* Generators in OCaml *) (* A stream of 'a values produced on-demand in effectful computations *) type 'a stream = Nil | Cons of 'a * (unit -> 'a stream) (* Two basic generator primitives *) (* Generator expressions and streams may nest. A prompt, the value of the type 'a stream Delimcc.prompt, identifies the enumerator of a stream for yield to generate. The prompt plays the role of a `loop label' in Perl, for example, permitting the loop control primitives `break' and `continue' to reach beyond the inner loop. Our yield can likewise reach beyond the inner enumerator, to an arbitrary outer enumerator/stream. *) val yield : 'a stream Delimcc.prompt -> (* The `exception wrapper' *) 'a -> (* The value to yield *) unit (* Reify a generator expression into a stream *) val msplit : 'a stream Delimcc.prompt -> (unit -> unit) -> 'a stream (* Re-export the new_prompt from Delimcc *) val new_prompt : unit -> 'a stream Delimcc.prompt;; (* A few useful functions on a stream, analogous to those from LogicT *) (* Take at most n elements from a stream, returning another stream *) val stream_take : int -> 'a stream -> 'a stream (* Map a function to a stream and collect the results in a list *) val stream_mapl : ('a -> 'b) -> 'a stream -> 'b list (* A simplified version of the above, for the case when the mapping function returns unit and no accumulation is needed. *) val stream_iter : ('a -> unit) -> 'a stream -> unit (* This is analogous to the for-loop *) val for_loop : 'a stream Delimcc.prompt -> (unit -> unit) -> ('a -> unit) -> unit (* Icon's find: [find s1 s2] generates the positions at which s1 occurs in s2. *) val pfind : int stream Delimcc.prompt val find : string -> string -> unit