From: Nicolas Cannasse <warplayer@fr...>  20030227 10:52:29

> (* > * Additions to the List module. > *) > > (* Generate the range of integers [a; a+1; ...; b] *) > > val range : int * int > int list would prefer : range : int > int > int list since it's not causing any overhead due to the tuple allocation ( integer are unboxed ) > (* List equivalent of Array.init *) > > val listi : int > (int > 'a) > 'a list ok , let's call it ExtList.init ! and so you have let range a b = ExtList.init (b  a) (fun x > x+a) and if I agree that List.init is missing, I don't think that the "range" is worth including in ExtList > (* List equivalent of Array.mapi *) > > val mapi : (int > 'a > 'b) > 'a list > 'b list > val iteri : (int > 'a > unit) > 'a list > unit ok I buy it > (* Reverse assoc *) > (* can also add rassq, mem_rassoc/rassq, remove_rassoc/rassq if needed *) > > val rassoc : 'b > ('a * 'b) list > 'a I reallly don't like theses. The usage of them are far from obvious > (* Tailrecursively compute rev (map f list1) @ list2 *) > > val rev_map_append : ('a > 'b) > 'a list > 'b list > 'b list same : I don't see the point This function seems very particular, I haven't ever needed it (or perhaps I don't remember) And I would like something doing that, I think I wouln't even check in any StandardLibrary if it exists. > (* Split [x1; x2; ...; xN] into [x1; ...; x{n}] and [x{n+1}; ...; xN] *) > > val split_nth : int > 'a list > 'a list * 'a list Agree, Looks a little like the npop from MList > (* Tailrecursively split [x1; x2; ...; xN] into > [x{n}; ...; x1] and [x{n+1}; ...; xN] *) > > val rev_split_nth : int > 'a list > 'a list * 'a list Don't agree. If users wants tailrecusive calls for such functions, I think they have to implement it since we're not going to provide for all the non tail recursive functions a corresponding tail recursive one. > (* Return the last element of a list. *) > > val last : 'a list > 'a Agree  need an exception :) > (* Insert x at position n in list. > Position 0 places x at the front; > position (length list) places x at the end. *) > > val insert : 'a > int > 'a list > 'a list Agree > (* Remove first occurrence of x, if any, from list. *) > val remove_first : 'a > 'a list > 'a list > > (* Remove all occurrences of x from list. *) > val remove : 'a > 'a list > 'a list > > (* Remove a subset of elements from a list. *) > val remove_subset : 'a list > 'a list > 'a list Actually I wonder if when you're using theses, you're not actualy using somehow a mutable list... > (* Rotate each element of a list to the left, > so that the head becomes the last element. *) > > val rotate_left : 'a list > 'a list Too much particular > (* Homogeneous version of List.fold_left. > Uses the head of the list as the initial value. *) > > val fold : ('a > 'a > 'a) > 'a list > 'a Same > (* Test whether the first list is a subset of the second. *) > > val subset : 'a list > 'a list > bool Agree, but I would add a functional comparator as first parameter. Perhaps when using such comparators, we could use an optional argument ?comp having a default of ( = ) > (* Return cartesian product of two lists. *) > > val product : 'a list > 'b list > ('a * 'b) list "join" is a better name. > (* Return all sublists of a list. *) > > val subsets : 'a list > 'a list list Pfiouu You're doing strange things with Ocaml , aren't you ? :) Statistics, is it ? > (* Return all nelement sublists of a list. *) > > val choose : int > 'a list > 'a list list > > (* Return all sublists with up to n elements. *) > > val choose_up_to : int > 'a list > 'a list list Too particular > (* Remove duplicates from a sorted list, > using a sortstyle comparison function that returns 0 for equality. *) > > val uniq : ('a > 'a > int) > 'a list > 'a list Why do not use a ('a > 'a > bool) on unsorted list ? complexity is the same > (* > * Additions to the String module. > *) > > (* String equivalents of Array.fold_left and Array.fold_right *) > > val string_fold_left : ('a > char > 'a) > 'a > string > 'a > val string_fold_right : (char > 'a > 'a) > 'a > string > 'a > > (* Convert between strings and lists of chars. *) > > val explode : string > char list > val implode : char list > string Theses four are interesting, but I don't realy see the need of using Strings as char list. Could you tell me about it ? > (* Convert between strings and lists of ints in the range 0 .. 255 *) > > val explode_bytes : string > int list > val implode_bytes : int list > string > > (* Like [index_from] but searches at most [len] chars. *) > (* can also add bounded_rindex if needed *) > > val bounded_index : string > pos:int > len:int > char > int Same > (* > * Miscellaneous control structures. > *) > > (* Compute f (g x) *) > (* It would be nice to have a standard infix operator for this. *) > > val compose : ('b > 'c) > ('a > 'b) > 'a > 'c Agree > (* Compute f^n x *) > > val iterate : ('a > 'a) > int > 'a > 'a Agree > (* Invoke (f ()) n times, for side effects. *) > > val repeat : int > (unit > unit) > unit > > (* Apply f to 0 .. n1, for side effects. *) > > val dotimes : int > (int > unit) > unit Better with a "for" loop. Done. Nicolas Cannasse 