You can simply define the generator as a stream using the language extension:
let range n = Stream.from (fun i -> if i < n then Some i else None);;
The syntax for cannot be used with this, but there is a set of functions provided by the Stream module to check the state of the stream and iterate over its elements.
try let r = range 10 in while true do Printf.printf "next element: %d\n" @@ Stream.next r done with Stream.Failure -> ();;
Or easier:
Stream.iter (Printf.printf "next element: %d\n") @@ range 10;;
You can also use the special syntax provided by the camlp4 preprocessor:
Stream.iter (Printf.printf "next element: %d\n") [< '11; '3; '19; '52; '42 >];;
Other features include creating streams from lists, strings, bytes, or even channels. The API documentation briefly describes the various features.
Special syntax allows you to compose them to return elements before or after, but at first it can be somewhat unintuitive:
let dump = Stream.iter (Printf.printf "next element: %d\n");; dump [< range 10; range 20 >];;
will create the elements of the first stream, and then take the second stream in the element ranked immediately after the rank of the last received element, so it will appear in this case, as if only the second stream had received an iteration.
To get all the elements, you can build a stream 'a Stream.t and then iterate recursively over each of them:
Stream.iter dump [< '(range 10); '(range 20) >];;
This will lead to the expected result.
I recommend reading an old OCaml book (available online ) for a better introduction to the topic.