From: Brian H. <bri...@ql...> - 2003-05-26 23:34:28
|
Replying to myself... On Mon, 26 May 2003, Brian Hurt wrote: > But you're right, count needs to be an optional thing. > val count: ExtStream.t -> int option where a return value of Some x means the stream has x elements, and a return value of None means that count is not implemented. This has the advantage of roping the type checker in to make sure everyone checks for the non-implemented version. Now, two possibilities for doing a destructive count (i.e. one that clones the ExtStream and then reads ahead to see how many items are left). The first one is: val destructive_count : ExtStream.t -> int let destructive_count enum = match enum.count () with Some x -> x | None -> let e = ExtStream.clone enum in let rec loop count = match e.next() with None -> count | Some _ -> loop (count + 1) in loop 0 i.e. we clone and loop everytime destructive_count is called. The other one is: val destructive_count: ExtStream.t -> ExtStream.t let destructive_count enum = let e = ExtStream.clone enum in let rec loop count = match e.next () in None -> count | Some _ -> loop (count + 1) in let countref = ref (loop 0) in let next () = match enum.next () with None -> None | Some x -> decr countref; Some x and count () = !countref in ExtStream.make next count In this case, we run through the enumeration only once- and create a new enumeration which decrements a reference every call to next. There are advantages and disadvantages to each. Brian |