From: Nicolas C. <war...@fr...> - 2003-02-27 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 > (* Tail-recursively 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 > (* Tail-recursively 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 tail-recusive 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 n-element 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 sort-style 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 .. n-1, for side effects. *) > > val dotimes : int -> (int -> unit) -> unit Better with a "for" loop. Done. Nicolas Cannasse |