diff --git a/sequence.ml b/sequence.ml index e761102..b5055f4 100644 --- a/sequence.ml +++ b/sequence.ml @@ -228,25 +228,39 @@ let to_set (type s) (type v) m seq = (fun set x -> S.add x set) S.empty seq -(** Iterate on maps. The functor must be instantiated with a map type *) -module Map(M : Map.S) = - struct - type 'a map = 'a M.t - type key = M.key - - let to_seq m = - from_iter (fun k -> M.iter (fun key value -> k (key, value)) m) - - let keys m = - from_iter (fun k -> M.iter (fun key _ -> k key) m) - - let values m = - from_iter (fun k -> M.iter (fun _ value -> k value) m) - - let of_seq seq = - fold (fun m (key,value) -> M.add key value m) M.empty seq +(** Conversion between maps and sequences. *) +module Map = struct + module type S = sig + type +'a map + include Map.S with type 'a t := 'a map + val to_seq : 'a map -> (key * 'a) t + val of_seq : (key * 'a) t -> 'a map + val keys : 'a map -> key t + val values : 'a map -> 'a t end + (** Adapt a pre-existing Map module to make it sequence-aware *) + module Adapt(M : Map.S) : S with type key = M.key and type 'a map = 'a M.t = struct + type 'a map = 'a M.t + + let to_seq m = from_iter (fun k -> M.iter (fun x y -> k (x,y)) m) + + let of_seq seq = fold (fun m (k,v) -> M.add k v m) M.empty seq + + let keys m = from_iter (fun k -> M.iter (fun x _ -> k x) m) + + let values m = from_iter (fun k -> M.iter (fun _ y -> k y) m) + + include M + end + + (** Create an enriched Map module, with sequence-aware functions *) + module Make(V : Map.OrderedType) : S with type key = V.t = struct + module M = Map.Make(V) + include Adapt(M) + end +end + (** {2 Pretty printing of sequences} *) (** Pretty print a sequence of ['a], using the given pretty printer diff --git a/sequence.mli b/sequence.mli index 8810a67..c9228bd 100644 --- a/sequence.mli +++ b/sequence.mli @@ -151,21 +151,24 @@ val of_set : (module Set.S with type elt = 'a and type t = 'b) -> 'b -> 'a t val to_set : (module Set.S with type elt = 'a and type t = 'b) -> 'a t -> 'b (** Convert the sequence to a set, given the proper set module *) -(** Iterate on maps. The functor must be instantiated with a map type *) -module Map(M : Map.S) : - sig - type 'a map = 'a M.t - type key = M.key - +(** Conversion between maps and sequences. *) +module Map : sig + module type S = sig + type +'a map + include Map.S with type 'a t := 'a map val to_seq : 'a map -> (key * 'a) t - - val keys : 'a map -> key t - - val values : 'a map -> 'a t - val of_seq : (key * 'a) t -> 'a map + val keys : 'a map -> key t + val values : 'a map -> 'a t end + (** Adapt a pre-existing Map module to make it sequence-aware *) + module Adapt(M : Map.S) : S with type key = M.key and type 'a map = 'a M.t + + (** Create an enriched Map module, with sequence-aware functions *) + module Make(V : Map.OrderedType) : S with type key = V.t +end + (** {2 Pretty printing of sequences} *) val pp_seq : ?sep:string -> (Format.formatter -> 'a -> unit) -> diff --git a/tests.ml b/tests.ml index 2ffe236..58c58ab 100644 --- a/tests.ml +++ b/tests.ml @@ -9,9 +9,15 @@ let pp_list ?(sep=", ") pp_item formatter l = module ISet = Set.Make(struct type t = int let compare = compare end) let iset = (module ISet : Set.S with type elt = int and type t = ISet.t) +module OrderedString = struct type t = string let compare = compare end +module SMap = Sequence.Map.Make(OrderedString) + +let my_map = SMap.of_seq (Sequence.of_list ["1", 1; "2", 2; "3", 3; "answer", 42]) + let sexpr = "(foo bar (bazz quux hello 42) world (zoo foo bar (1 2 (3 4))))" let _ = + (* lists *) let l = [0;1;2;3;4;5;6] in let l' = Sequence.to_list (Sequence.filter (fun x -> x mod 2 = 0) (Sequence.of_list l)) in @@ -39,11 +45,21 @@ let _ = (Sequence.of_array (Sequence.to_array (Sequence.append (Sequence.take 5 (Sequence.of_list l3)) (Sequence.of_list l4)))); + (* maps *) + Format.printf "@[map: %a@]@." + (Sequence.pp_seq (fun formatter (k,v) -> Format.fprintf formatter "\"%s\" -> %d" k v)) + (SMap.to_seq my_map); + let module MyMapSeq = Sequence.Map.Adapt(Map.Make(OrderedString)) in + let my_map' = MyMapSeq.of_seq (Sequence.of_list ["1", 1; "2", 2; "3", 3; "answer", 42]) in + Format.printf "@[map: %a@]@." + (Sequence.pp_seq (fun formatter (k,v) -> Format.fprintf formatter "\"%s\" -> %d" k v)) + (MyMapSeq.to_seq my_map'); (* sum *) let n = 100000000 in let sum = Sequence.fold (+) 0 (Sequence.take n (Sequence.repeat 1)) in Format.printf "%dx1 = %d@." n sum; assert (n=sum); + (* sexpr *) let s = Sexpr.of_seq (Sexpr.lex (Sequence.of_str sexpr)) in let s = Sexpr.of_seq (Sequence.map (function | `Atom s -> `Atom (String.capitalize s) | tok -> tok)