caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "David Allsopp" <dra-news@metastack.com>
To: <caml-list@yquem.inria.fr>
Subject: RE: [Caml-list] Preferred Way to Split a List
Date: Tue, 30 Oct 2007 12:30:36 -0000	[thread overview]
Message-ID: <000001c81af0$ad1ad830$017ca8c0@countertenor> (raw)
In-Reply-To: <4725A915.3020005@univ-savoie.fr>

Christophe Raffalli wrote:
> let split l n =
>   let rec aux acc l n =
>      if n = 0 then List.rev acc, l
>      else match l with
>         [] -> List.rev acc, []
>      | hd::l -> aux (hd::acc) l (n-1)
>   in aux [] l n

I'd go one stage further and use Obj.magic to eliminate the List.rev calls
(cf. ExtList.List in ExtLib). I'm sensibly wary of using Obj.magic in
general but find it acceptable here because its use is hidden within the
function (you are constructing a new list anyway, you just use Obj.magic to
allow tail-consing instead) - and there is no risk of "entertaining" side
effects (cf. John's earlier email!). I've got tail-consing wrapped in a few
extra functions in List so that this would become:

let split l n =
  let acc = List.tlempty ()
  in
    let rec aux l n =
       if n = 0 then (List.tlresult acc, l)
       else match l with
              []    -> (List.tlresult acc, [])
            | hd::l -> List.tlcons hd acc; aux l (n-1)
    in
      aux l n


David


PS List.tlempty:        returns a new, empty tail-consing list
   List.tlcons x tlist: adds x to the end of the given tlist and returns
                        the same tlist pointer
   List.tlresult tlist: casts an 'a tlist to an 'a list - and marks the
                        tlist as "exported", preventing future tail-consing
                        (which would violate the semantics of O'Caml 'a
                        lists)


  parent reply	other threads:[~2007-10-30 12:30 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-29 23:33 Robert Fischer
2007-10-30  0:45 ` [Caml-list] " Matthew William Cox
2007-10-30 13:18   ` Robert Fischer
2007-11-03  3:06     ` Nathaniel Gray
2007-10-30  1:20 ` Julien Moutinho
2007-10-30  1:38   ` Karl Zilles
2007-10-30  5:46   ` skaller
2007-10-30  7:58     ` Alain Frisch
2007-10-29  9:34       ` Christophe Raffalli
2007-10-30 11:31         ` skaller
2007-10-30 12:30         ` David Allsopp [this message]
2007-10-30 15:03           ` Christophe Raffalli
2007-10-30 11:15       ` skaller
2007-10-30 13:05         ` Brian Hurt
2007-10-30  7:50 ` Jon Harrop
2007-10-30 13:20   ` Robert Fischer

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='000001c81af0$ad1ad830$017ca8c0@countertenor' \
    --to=dra-news@metastack.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;
as well as URLs for NNTP newsgroup(s).