From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id RAA31909; Tue, 17 Aug 2004 17:19:49 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id RAA30546 for ; Tue, 17 Aug 2004 17:19:48 +0200 (MET DST) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.204]) by nez-perce.inria.fr (8.12.10/8.12.10) with ESMTP id i7HFJkmL013260 for ; Tue, 17 Aug 2004 17:19:47 +0200 Received: by mproxy.gmail.com with SMTP id 75so99879rnl for ; Tue, 17 Aug 2004 08:19:40 -0700 (PDT) Received: by 10.38.102.15 with SMTP id z15mr133530rnb; Tue, 17 Aug 2004 08:19:39 -0700 (PDT) Message-ID: Date: Tue, 17 Aug 2004 11:19:39 -0400 From: John Prevost Reply-To: John Prevost To: Richard Jones Subject: Re: [Caml-list] Are map and iter guaranteed to be called in forwards order? Cc: Caml Mailing List In-Reply-To: <20040817145653.GA12345@annexia.org> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit References: <20040817120053.GA9749@annexia.org> <20040817145653.GA12345@annexia.org> X-Miltered: at nez-perce with ID 41222212.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Loop: caml-list@inria.fr X-Spam: no; 0.00; prevost:01 prevost:01 caml-list:01 2004:99 'g':01 val:01 char:01 'g':01 val:01 incr:01 char:01 incr:01 int:01 int:01 it'd:01 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk On Tue, 17 Aug 2004 15:56:53 +0100, Richard Jones wrote: > This came up because I wanted a sensible way to number a list of > items. The obvious imperative approach is: > > # let items = ['a';'c';'e';'g';'i'];; > val items : char list = ['a'; 'c'; 'e'; 'g'; 'i'] > # let i = ref 0;; > val i : int ref = {contents = 0} > # let items = List.map (fun item -> let n = !i in incr i; n, item) items;; > val items : (int * char) list = > [(0, 'a'); (1, 'c'); (2, 'e'); (3, 'g'); (4, 'i')] > > The functional approach is comparatively long-winded: you have to > effectively write your own loop explicitly, and the obvious way to > write it isn't tail recursive, so you have to do it with accumulators. > > It'd be nicer to have a library HOF to do this. How about fold? let number l = let _, l = List.fold_left (fun (n, l) i -> (n+1, (n, i)::l)) (0, []) l in List.rev l You could even do fold with side effects if you really want to: let number' l = let i = ref 0 in let l = List.fold_left (fun l x -> let n = !i in incr i; (n, x) :: l) [] l in List.rev l Or define your own version of map, that you have explicitly written to be based on fold_left, which allows you to be sure that it will always work the same way: let folding_map f l = let l = List.fold_left (fun l x -> (f x)::l) [] l in List.rev l John. ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners