From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL,HTML_MESSAGE, MIME_HTML_ONLY autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by yquem.inria.fr (Postfix) with ESMTP id 85EE4BC6B for ; Tue, 30 Oct 2007 14:20:23 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ao8CANnMJkfQccgFfWdsb2JhbACCPTWKSYEkAgkEBgIPEQc X-IronPort-AV: E=Sophos;i="4.21,347,1188770400"; d="scan'208,217";a="3734326" Received: from lax-green-bigip-5.dreamhost.com (HELO looneymail-a1.g.dreamhost.com) ([208.113.200.5]) by mail2-smtp-roc.national.inria.fr with ESMTP; 30 Oct 2007 14:20:22 +0100 Received: from carols-computer-3.local (unknown [74.202.102.226]) by looneymail-a1.g.dreamhost.com (Postfix) with ESMTP id 011B015F43A for ; Tue, 30 Oct 2007 06:20:21 -0700 (PDT) Message-ID: <47272F94.1030707@fischerventure.com> Date: Tue, 30 Oct 2007 08:20:20 -0500 From: Robert Fischer User-Agent: Thunderbird 2.0.0.6 (Macintosh/20070728) MIME-Version: 1.0 To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Preferred Way to Split a List References: <47266DB7.1020009@SmokejumperIT.com> <200710300750.26912.jon@ffconsultancy.com> In-Reply-To: <200710300750.26912.jon@ffconsultancy.com> Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; combinator:01 val:01 val:01 wrote:01 wrote:01 rec:01 caml-list:01 int:01 int:01 arbitrary:02 arbitrary:02 arg:03 tend:03 element:03 let:03 Thanks for the sane response.

~~ Robert.

Jon Harrop wrote:
On Monday 29 October 2007 23:33, Robert Fischer wrote:
  
What is the preferred way to split a list into two, at an arbitrary
point?  There's lots of ways you could do it, but I'm not sure if
there's a standard best practice for this.
    

I tend to write a combinator that nests an arbitrary number of function 
applications:

# let rec nest n f x =
    if n=0 then x else nest (n-1) f (f x);;
val nest : int -> ('a -> 'a) -> 'a -> 'a = <fun>

and then apply this to a function that moves head elements:

# let aux = function
    | front, h::back -> h::front, back
    | _ -> invalid_arg "aux";;
val aux : 'a list * 'a list -> 'a list * 'a list = <fun>

Then I write a "chop" function in terms of those two:

# let chop n list =
    nest n aux ([], list);;
val chop : int -> 'a list -> 'a list * 'a list = <fun>

For example, splitting after the fourth element:

# chop 4 [1;2;3;4;5;6;7;8;9];;
- : int list * int list = ([4; 3; 2; 1], [5; 6; 7; 8; 9])

Note that the front list is reversed.

PS: Ignore any responses that even mention Obj.