From: Janne H. <jjh...@gm...> - 2005-08-09 17:24:34
|
Hi all, I propose the addition of two new functions into ExtList.List module. I've found these to be useful in parsing and manipulating token lists. I think these might be useful for other people as well. I'm not sure if the naming is good, so feedback is welcome. There's already a function called "split" in the List module, so I guess I need to come up with some other name for it. The name stems from the functions similarity to String.split. Comments are welcome! First one is called fold_left_while. It works the same way as fold_left except that it breaks the loop as soon as a "while predicate" returns false. This is similar to dropwhile and takewhile functions in List. I've found this to be useful in many cases. val fold_left_while : ('a -> 'b -> bool) -> ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a =3D <fun> (* Fold while (while_pred accu x) is true. *) let rec fold_left_while while_pred f accu =3D function [] -> accu | x::xs ->=20 if while_pred accu x then fold_left_while while_pred f (f accu x) xs else accu Example: As an example of its usefulness, let's implement ExtList.List.takewhile with fold_left_while: let takewhile f lst =3D=20 List.rev (fold_left_while (fun _ e -> f e) (fun acc e -> e::acc) [] lst) * *=20 The second function is called split. I've used it to split lists of tokens into sublists (such as splitting argument lists by COMMA-token). val split : ('a -> bool) -> 'a list -> 'a list list =3D <fun> let rec split pred =3D=20 let rec loop (single_acc,accu) =3D function x::xs when pred x -> loop ([],single_acc::accu) xs | x::xs -> loop (x::single_acc,accu) xs | [] ->=20 List.rev (List.map List.rev (single_acc::accu)) in loop ([],[]) Example: # split (fun c -> c =3D 0) [1; 2; 0; 3; 4; 5; 0; 5];; - : int list list =3D [[1; 2]; [3; 4; 5]; [5]] Best regards, Janne |