## ocaml-lib-devel

 [Ocaml-lib-devel] List.map_pairs From: Richard Jones - 2005-08-10 16:34:40 ```On the subject of new list functions, how about: let rec list_map_pairs f = function | [] | [_] -> invalid_arg "list_map_pairs" | [x; y] -> [f x y] | x :: (y :: _ as xs) -> f x y :: list_map_pairs f xs We use this sort of pattern to disaggregate data which has been collected using an incrementing counter - something like this: # let xs = [ 0; 1; 4; 5; 5; 5; 8; 9; 9; 10 ];; val xs : int list = [0; 1; 4; 5; 5; 5; 8; 9; 9; 10] # list_map_pairs (fun a b -> b - a) xs;; - : int list = [1; 3; 1; 0; 0; 3; 1; 0; 1] Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ```
 Re: [Ocaml-lib-devel] List.map_pairs From: Nicolas Cannasse - 2005-08-10 17:24:49 ```> On the subject of new list functions, how about: > > let rec list_map_pairs f = function > | [] | [_] -> invalid_arg "list_map_pairs" > | [x; y] -> [f x y] > | x :: (y :: _ as xs) -> > f x y :: list_map_pairs f xs > > We use this sort of pattern to disaggregate data which has been > collected using an incrementing counter - something like this: > > # let xs = [ 0; 1; 4; 5; 5; 5; 8; 9; 9; 10 ];; > val xs : int list = [0; 1; 4; 5; 5; 5; 8; 9; 9; 10] > # list_map_pairs (fun a b -> b - a) xs;; > - : int list = [1; 3; 1; 0; 0; 3; 1; 0; 1] > > Rich. I think that it's not very the Ocaml spirit of handling pairs, in general you will first transform your "int list" into an "(int * int) list" with error handling and then treat pairs uniformly in a typesafe manner. Nicolas ```
 Re: [Ocaml-lib-devel] List.map_pairs From: Richard W. M. Jones - 2005-08-10 17:27:48 ```On Wed, Aug 10, 2005 at 07:30:42PM +0200, Nicolas Cannasse wrote: > > On the subject of new list functions, how about: > > > > let rec list_map_pairs f = function > > | [] | [_] -> invalid_arg "list_map_pairs" > > | [x; y] -> [f x y] > > | x :: (y :: _ as xs) -> > > f x y :: list_map_pairs f xs > > > > We use this sort of pattern to disaggregate data which has been > > collected using an incrementing counter - something like this: > > > > # let xs = [ 0; 1; 4; 5; 5; 5; 8; 9; 9; 10 ];; > > val xs : int list = [0; 1; 4; 5; 5; 5; 8; 9; 9; 10] > > # list_map_pairs (fun a b -> b - a) xs;; > > - : int list = [1; 3; 1; 0; 0; 3; 1; 0; 1] > > > > Rich. > > I think that it's not very the Ocaml spirit of handling pairs, in general > you will first transform your "int list" into an "(int * int) list" with > error handling and then treat pairs uniformly in a typesafe manner. Well OK, but we don't even have a function to do the int list -> (int * int) list transformation. Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ```
 [Ocaml-lib-devel] Re: List.map_pairs From: Alan Post - 2005-08-10 18:36:39 ```In article <20050810173844.GB6103@...>, Richard W. M. Jones wrote: > > Well OK, but we don't even have a function to do the > int list -> (int * int) list transformation. A fold using a ref would work, yes? ```
 Re: [Ocaml-lib-devel] Re: List.map_pairs From: Richard Jones - 2005-08-14 10:00:15 ```On Wed, Aug 10, 2005 at 06:34:19PM +0000, Alan Post wrote: > In article <20050810173844.GB6103@...>, Richard W. M. Jones wrote: > > > > Well OK, but we don't even have a function to do the > > int list -> (int * int) list transformation. > > A fold using a ref would work, yes? Something like that might, but the whole point of HOFs is to avoid having to write ugly hacks all the time :-) Here are my two functions for taking pairs of elements from lists. FWIW, I have used both of these patterns in real code on more than one occasion, although the first one is used a lot more frequently than the second (for disaggregating our counted data): # let rec take_pairs = function | [] | [_] -> invalid_arg "take_pairs" | [x; y] -> [x, y] | x :: (y :: _ as xs) -> (x, y) :: take_pairs xs;; val take_pairs : 'a list -> ('a * 'a) list = # take_pairs [1; 2; 3; 4; 5; 6; 7; 8];; - : (int * int) list = [(1, 2); (2, 3); (3, 4); (4, 5); (5, 6); (6, 7); (7, 8)] # let rec take_in_twos = function | [] -> [] | [_] -> invalid_arg "take_in_twos" | x :: y :: xs -> (x, y) :: take_in_twos xs;; val take_in_twos : 'a list -> ('a * 'a) list = # take_in_twos [1; 2; 3; 4; 5; 6; 7; 8];; - : (int * int) list = [(1, 2); (3, 4); (5, 6); (7, 8)] Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ```
 [Ocaml-lib-devel] Re: List.map_pairs From: Alan Post - 2005-08-14 17:00:23 ```In article <20050814101135.GA7606@...>, Richard Jones wrote: > On Wed, Aug 10, 2005 at 06:34:19PM +0000, Alan Post wrote: >> In article <20050810173844.GB6103@...>, Richard W. M. Jones wrote: >> > >> > Well OK, but we don't even have a function to do the >> > int list -> (int * int) list transformation. >> >> A fold using a ref would work, yes? > > Something like that might, but the whole point of HOFs is to avoid > having to write ugly hacks all the time :-) OK, here's a tail-recursive function using a fold without a ref: let take_pairs = let f (i,l) j = (j, (i,j)::l) in function | [] -> [] | h::tl -> List.rev (snd (List.fold_left f (h, []) tl)) ```