2007/10/2, Olivier Andrieu : > > On 10/2/07, kirillkh wrote: > > OK, so I'll give up the parsing/buffering part and only leave efficient > > exception handling. This should leave the user free to do anything with > it, > > but prevent performance pitfalls. The following is based on Mattias > > Engdegard's code: > > > > (* I couldn't figure out, how to declare a polymorphic exception > properly *) > > exception Done of 'a > > > > let fold_file (file: in_channel) > > (read_func: in_channel->'a) > > (elem_func: 'a->'b->'b) > > (seed: 'b) = > > let rec loop prev_val = > > let input = > > try read_func file > > with End_of_file -> raise (Done prev_val) > > in > > let combined_val = elem_func input prev_val in > > loop combined_val > > in > > try loop seed with Done x -> x > > > > And the usage for line counting: > > > > let line_count filename = > > let f = open_in filename in > > let counter _ count = count + 1 in > > fold_file f readline counter 0 > > > > Since it's library code, we can tolerate the little annoyance of the > second > > try-catch. As far as I can tell, this code has the same performance > > characteristics as yours: no consing + tail recursion. Any other > problems > > with it? > > well apart from the fact that you cannot have "polymorphic exceptions" > in OCaml, this kind of code is IMHO much more natural with an > imperative loop instead of a functional one: > > > let fold_file read chan f init = > let acc = ref init in > begin > try while true do > let d = read chan in > acc := f d !acc > done > with End_of_file -> () > end ; > !acc > > -- > Olivier > A little weird to see such inherently functional construct as fold implemented imperatively. But it's fine with me, as long as it does the job. I wonder, though, how would the performance of a line counter based on your code compare with the one suggested by Brian.