From: Jon Harrop <jon@ffconsultancy.com>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Generators/iterators and lazy evaluation?
Date: Thu, 5 Apr 2007 00:53:41 +0100 [thread overview]
Message-ID: <200704050053.41426.jon@ffconsultancy.com> (raw)
In-Reply-To: <CCF54B6E-E0E6-48B3-93A2-458FFF5FD769@rice.edu>
On Wednesday 04 April 2007 17:33, Raj B wrote:
> A generator in Python can be thought of as an arbitrarily generated
> 'lazy list'. As an example
> the following is a generator capable of generating powers of 2 upto a
> max value.
>
> def pow2(max):
> start = 0
> while (start .lt. max):
> yield 2^start
> start += 1
>
> The 'yield' statement is the point where the function returns the
> next value and suspends itself until the next time it is 'forced'. At
> that time it resumes execution where it left off.
>
> OCaml makes this particularly hard to implement this due to lack of
> 'control flow' features
Might I suggest deferring judgement until you have seen some OCaml solutions.
$ ocaml -rectypes camlp4o.cma
Objective Caml version 3.10.0+beta
Camlp4 Parsing version 3.10.0+beta
#
Use a lazy list sum type:
# type 'a llist = Nil | Cons of 'a * 'a llist lazy_t;;
type 'a llist = Nil | Cons of 'a * 'a llist lazy_t
# let rec pow2 ?(i=1) n =
if n>0 then Cons(i, lazy(pow2 ~i:(2*i) (n-1))) else Nil;;
val pow2 : ?i:int -> int -> int llist = <fun>
For example:
# let rec list_of = function
| Nil -> []
| Cons(h, t) -> h :: list_of(Lazy.force t);;
val list_of : 'a llist -> 'a list = <fun>
# list_of(pow2 10);;
- : int list = [1; 2; 4; 8; 16; 32; 64; 128; 256; 512]
Use an inferred lazy list type (polymorphic variant):
# let rec pow2 ?(i=1) n =
if n>0 then `Cons(i, lazy(pow2 ~i:(2*i) (n-1))) else `Nil;;
val pow2 : ?i:int -> int -> ([> `Cons of int * 'a lazy_t | `Nil ] as 'a) =
<fun>
Return a lazy tail (using -rectypes):
# let rec pow2 ?(i=1) n =
if n>0 then Some(i, lazy(pow2 ~i:(2*i) (n-1))) else None;;
val pow2 : ?i:int -> int -> ((int * 'a lazy_t) option as 'a) = <fun>
Return a functional tail (using -rectypes):
# let rec pow2 ?(i=1) j n () =
if n>0 then Some(i, pow2 ~i:(2*i) (n-1)) else None;;
val pow2 : ?i:int -> int -> (int -> unit -> (int * 'a) option as 'a) = <fun>
Return a lazy stream (using camlp4 stream parsing syntax extension):
# let rec pow2 ?(i=1) n =
if i<n then [<'i; pow2 ~i:(2*i) (n-1)>] else [<>];;
val pow2 : ?i:int -> int -> int Stream.t = <fun>
The moral is: don't try to write idiomatic Python in OCaml.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
OCaml for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists
next prev parent reply other threads:[~2007-04-04 23:58 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-04 16:33 Raj B
2007-04-04 20:10 ` [Caml-list] " Mathias Kende
2007-04-04 20:46 ` Alain Frisch
2007-04-04 21:16 ` Erik de Castro Lopo
2007-04-04 21:37 ` Erik de Castro Lopo
2007-04-04 22:55 ` Bill Wood
2007-04-05 2:49 ` skaller
2007-04-05 16:41 ` Richard Jones
2007-04-04 23:53 ` Jon Harrop [this message]
2007-04-05 3:13 ` Erik de Castro Lopo
2007-04-05 5:58 ` Alain Frisch
2007-04-05 20:35 ` Jon Harrop
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200704050053.41426.jon@ffconsultancy.com \
--to=jon@ffconsultancy.com \
--cc=caml-list@yquem.inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox