From: Richard J. <ri...@an...> - 2004-12-16 12:05:18
|
On Thu, Dec 16, 2004 at 10:22:05AM +0100, Nicolas Cannasse wrote: > Hi list, >=20 > It's been long time without activity on this list, I have been quite busy > lately but I keep on fixing bugs when reports are coming sometimes ;). Ri= ght > now the ExtLib acheivements are pretty good : I am a happy ExtLib user an= d I > don't feel anymore when I write Ocaml that I miss all theses functions fr= om > Stdlib. That's good, and I hope you feel same. >=20 > As for the future, I am not certain which path we should follow. I tend to > appreciate the current shape of ExtLib and I'm not wishing to include a l= ot > more modules, but other people might think different. What I would like to > be included in ExtLib would be small Xml and Date modules, but I'm not su= re > we can reach agreement on what should be put inside theses ;). Any insigh= ts > or wishes are welcome ! ExtLib works great for me. The only thing I'd like to see is more of the same. Some ideas: List.takewhile and List.dropwhile still seem to be missing (I posted a patch for this on list some time ago). Simple config file parsing. YAML-compatibility would be awesome. Or take a look at ConfigParser in JG's MissingLib. List.range: let rec range a b =3D if a <=3D b then a :: range (a+1) b else [] String.truncate: let truncate ?(with_dots =3D false) ?(dots =3D " ...") n str =3D if String.length str < n then str else ( if not with_dots then String.sub str 0 n else ( let n =3D n - String.length dots in let str =3D String.sub str 0 n in str ^ dots ) ) Controversial, because they only work on ASCII-compatible string encodings (ie. ASCII, UTF-8, ISO-8859-1, but not UCS-2), but extremely useful: val isspace : char -> bool val isalpha : char -> bool val isdigit : char -> bool val isalnum : char -> bool val islower : char -> bool val isupper : char -> bool val isxdigit : char -> bool =46rom this you can have trimming functions: let triml ?(test =3D isspace) str =3D let i =3D ref 0 in let n =3D ref (String.length str) in while !n > 0 && test str.[!i]; do decr n; incr i done; if !i =3D 0 then str else String.sub str !i !n =20 let trimr ?(test =3D isspace) str =3D let n =3D ref (String.length str) in while !n > 0 && test str.[!n-1]; do decr n done; if !n =3D String.length str then str else String.sub str 0 !n =20 let trim ?test str =3D trimr ?test (triml ?test str) And also String.for_all / String.exists functions: let string_for_all f str =3D let len =3D String.length str in let rec loop i =3D if i =3D len then true else ( let c =3D str.[i] in if not (f c) then false else loop (i+1) ) in loop 0 =20 let string_exists f str =3D let len =3D String.length str in let rec loop i =3D if i =3D len then false else ( let c =3D str.[i] in if f c then true else loop (i+1) ) in loop 0 let string_is_whitespace =3D string_for_all isspace List.uniq and List.sort_uniq: let rec uniq ?(cmp =3D Pervasives.compare) =3D function [] -> [] | [x] -> [x] | x :: y :: xs when compare x y =3D 0 -> uniq (x :: xs) | x :: y :: xs -> x :: uniq (y :: xs) =20 let sort_uniq ?cmp xs =3D let xs =3D List.sort ?cmp xs in let xs =3D uniq ?cmp xs in xs List.group_by is useful when you're pulling stuff out of a database: let group_by ?(cmp =3D Pervasives.compare) ls =3D let ls' =3D List.fold_left (fun acc (day1, x1) -> match acc with [] -> [day1, [x1]] | (day2, ls2) :: acctl -> if cmp day1 day2 =3D 0 then (day1, x1 :: ls2) :: acctl else (day1, [x1]) :: acc) [] ls in let ls' =3D List.rev ls' in List.map (fun (x, xs) -> x, List.rev xs) ls' Meta-functions, like in standard ML: let notf f =3D fun v -> not (f v) That'll do for the moment, I think! Rich. --=20 Richard Jones. http://www.annexia.org/ http://www.j-london.com/ >>> http://www.team-notepad.com/ - collaboration tools for teams <<< Merjis Ltd. http://www.merjis.com/ - improving website return on investment Write Apache modules in OCaml - http://www.merjis.com/developers/mod_caml |