caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Brian Rogoff <bpr@best.com>
To: John Max Skaller <skaller@ozemail.com.au>
Cc: Mark Seaborn <mrs35@cam.ac.uk>, caml-list@inria.fr
Subject: Re: [Caml-list] two unrelated questions
Date: Tue, 1 May 2001 14:08:50 -0700 (PDT)	[thread overview]
Message-ID: <Pine.BSF.4.21.0105011343400.11466-100000@shell5.ba.best.com> (raw)
In-Reply-To: <3AE89F2E.622B7EFC@ozemail.com.au>

On Fri, 27 Apr 2001, John Max Skaller wrote:
> Mark Seaborn wrote:
> > Another way of doing it is to CPS-convert the fold function to get
> > something like:
> > 
> > let rec foldc kons knil l = match l with
> >   | [] -> knil
> >   | x::xs -> kons x knil (fun rest -> foldc kons rest xs)
> 
> > This is more powerful than fold, but also harder to understand,
> 
> 	You're not kidding, on both counts :-)

I admit, I'm a sucker for CPS tricks. They are kind of hard to follow
sometimes, even for the initiated. 

> 	It's also 'ugly', because it only works for lists,
> but this is only because you hard coded the destructor.
> Passing it as an argument:
> 
>   let rec foldc remove kons knil l = match remove l with
> 	| (_,None) -> knil
> 	| (xs,Some x) -> kons x knil (fun rest -> foldc remove kons rest xs)
> 
>   let foldc_list = foldc (fun l -> match l with 
> 		| [] -> l,None
> 		| x::xs -> xs,Some x)

Yes, this is better. You can also use it with the inductive graph types 
defined by Martin Erwig. He names his destructor "match" (I rename it 
"extract" in my version of his library) and his constructor embed; the 
destructor takes a graph to a "context" (a node with incoming and outgoing
edges) and a graph with that context removed. 

It also fits on to OCaml Sets nicely too. Of course, you should always
remember that the value restriction sucks and that eta expansion is your
friend, and write it like this ;-)

let set_destruct s = 
  if is_empty s then (s, None) 
  else 
    let elt = PolySet.choose s in 
    let s'  = PolySet.remove elt s in 
    (s', Some elt) (* another case for left to right :-) *)

let foldc_set kons knil l = foldc set_destruct kons knil l 

> It's a pity there is no such destructor for a Hashtbl. 
> [All C++ STL data structures have read iterators, which 
> amount to destructors]

Are they really the same? I think of STL style iterators as being more 
similar to array indices, and arrays (and hashtables) are not defined
inductively like lists, trees, and graphs, etc. 

As I'm sure you know, there is an easy enough transformation from
hashtables (and arrays) to lists, like the following 

let pairs_of_hashtbl ht = 
  let pl_ref = ref [] in 
  let fn a b = (pl_ref := (a,b)::(!pl_ref) in 
  (Hashtbl.iter fn ht; !pl_ref)

which gives you a simple adaptor for folds. I think it's a pity from this 
POV that Map doesn't have an "is_empty" predicate and a "choose" which 
allow you to hand code a destructor analogous to your list destructor and
the set destructor above. 

-- Brian


-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


  reply	other threads:[~2001-05-01 21:08 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-04-25 21:08 Chris Hecker
2001-04-26  0:38 ` Patrick M Doane
2001-04-26  6:04   ` Judicaël Courant
2001-04-26 12:06     ` John Max Skaller
2001-04-27  9:12       ` Anton Moscal
2001-04-29 22:24         ` Brian Rogoff
2001-04-30 18:57           ` Fergus Henderson
2001-05-01  1:31           ` Jacques Garrigue
2001-05-01 12:45             ` [Caml-list] " Ken Friis Larsen
2001-04-27 15:09       ` [Caml-list] " Brian Rogoff
2001-04-27 17:49         ` John Max Skaller
2001-04-26  8:22   ` Andreas Rossberg
2001-04-26  1:13 ` Jacques Garrigue
2001-04-26 13:47 ` Xavier Leroy
2001-04-26 22:34   ` Chris Hecker
2001-04-26 16:57 ` Mark Seaborn
2001-04-26 22:20   ` John Max Skaller
2001-05-01 21:08     ` Brian Rogoff [this message]
2001-05-01 23:30       ` John Max Skaller
2001-05-02  0:03       ` John Max Skaller
2001-05-01 17:25 Dave Berry

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=Pine.BSF.4.21.0105011343400.11466-100000@shell5.ba.best.com \
    --to=bpr@best.com \
    --cc=caml-list@inria.fr \
    --cc=mrs35@cam.ac.uk \
    --cc=skaller@ozemail.com.au \
    /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;
as well as URLs for NNTP newsgroup(s).