From de859a844d998744da229a5a843e12ac406fa6b3 Mon Sep 17 00:00:00 2001 From: jkloos Date: Tue, 5 Apr 2016 16:27:30 +0200 Subject: [PATCH 1/3] Added map/mapi to some of the map types. --- src/data/CCIntMap.ml | 12 ++++++++++++ src/data/CCIntMap.mli | 4 ++++ src/data/CCTrie.ml | 33 +++++++++++++++++++++++++++++++++ src/data/CCTrie.mli | 6 ++++++ src/data/CCWBTree.ml | 14 ++++++++++++++ src/data/CCWBTree.mli | 6 ++++++ 6 files changed, 75 insertions(+) diff --git a/src/data/CCIntMap.ml b/src/data/CCIntMap.ml index 63a16c3a..227ea9a4 100644 --- a/src/data/CCIntMap.ml +++ b/src/data/CCIntMap.ml @@ -287,6 +287,18 @@ let rec fold f t acc = match t with let cardinal t = fold (fun _ _ n -> n+1) t 0 +let rec mapi f t = match t with + | E -> E + | L (k, v) -> L (k, f k v) + | N (p, s, l, r) -> + N (p, s, mapi f l, mapi f r) + +let rec map f t = match t with + | E -> E + | L (k, v) -> L (k, f v) + | N (p, s, l, r) -> + N (p, s, map f l, map f r) + let rec choose_exn = function | E -> raise Not_found | L (k, v) -> k, v diff --git a/src/data/CCIntMap.mli b/src/data/CCIntMap.mli index d3622db9..c4a7901d 100644 --- a/src/data/CCIntMap.mli +++ b/src/data/CCIntMap.mli @@ -66,6 +66,10 @@ val iter : (int -> 'a -> unit) -> 'a t -> unit val fold : (int -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b +val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t + +val map : ('a -> 'b) -> 'a t -> 'b t + val choose : 'a t -> (int * 'a) option val choose_exn : 'a t -> int * 'a diff --git a/src/data/CCTrie.ml b/src/data/CCTrie.ml index 36b0ddf3..c161c7d7 100644 --- a/src/data/CCTrie.ml +++ b/src/data/CCTrie.ml @@ -75,6 +75,12 @@ module type S = sig val fold : ('b -> key -> 'a -> 'b) -> 'b -> 'a t -> 'b (** Fold on key/value bindings. Will use {!WORD.of_list} to rebuild keys. *) + val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t + (** Map values in the try. Will use {!WORD.of_list} to rebuild keys. *) + + val map : ('a -> 'b) -> 'a t -> 'b t + (** Map values in the try, not giving keys to the mapping function. *) + val iter : (key -> 'a -> unit) -> 'a t -> unit (** Same as {!fold}, but for effectful functions *) @@ -356,6 +362,33 @@ module Make(W : WORD) = struct T.fold (fun acc k v -> (k,v) :: acc) [] t1 \ |> List.sort Pervasives.compare = List.sort Pervasives.compare l1 *) + let mapi f t = + let rec map_ prefix t = match t with + | Empty -> Empty + | Cons (c, t') -> Cons (c, map_ (_difflist_add prefix c) t') + | Node (v, map) -> + let v' = match v with + | None -> None + | Some v -> Some (f (W.of_list (prefix [])) v) + in let map' = + M.mapi (fun c t' -> + let prefix' = _difflist_add prefix c in + map_ prefix' t') + map + in Node (v', map') + in map_ _id t + + let map f t = + let rec map_ = function + | Empty -> Empty + | Cons (c, t') -> Cons (c, map_ t') + | Node (v, map) -> + let v' = match v with + | None -> None + | Some v -> Some (f v) + in let map' = M.map map_ map + in Node (v', map') + in map_ t let iter f t = _fold diff --git a/src/data/CCTrie.mli b/src/data/CCTrie.mli index cc0c7505..5c49c1a5 100644 --- a/src/data/CCTrie.mli +++ b/src/data/CCTrie.mli @@ -75,6 +75,12 @@ module type S = sig val fold : ('b -> key -> 'a -> 'b) -> 'b -> 'a t -> 'b (** Fold on key/value bindings. Will use {!WORD.of_list} to rebuild keys. *) + val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t + (** Map values, giving both key and value. Will use {!WORD.of_list} to rebuild keys. *) + + val map : ('a -> 'b) -> 'a t -> 'b t + (** Map values, giving only the value. *) + val iter : (key -> 'a -> unit) -> 'a t -> unit (** Same as {!fold}, but for effectful functions *) diff --git a/src/data/CCWBTree.ml b/src/data/CCWBTree.ml index d7c0b895..bdff0d45 100644 --- a/src/data/CCWBTree.ml +++ b/src/data/CCWBTree.ml @@ -97,6 +97,10 @@ module type S = sig val fold : f:('b -> key -> 'a -> 'b) -> x:'b -> 'a t -> 'b + val mapi : f:(key -> 'a -> 'b) -> 'a t -> 'b t + + val map : f:('a -> 'b) -> 'a t -> 'b t + val iter : f:(key -> 'a -> unit) -> 'a t -> unit val split : key -> 'a t -> 'a t * 'a option * 'a t @@ -368,6 +372,16 @@ module MakeFull(K : KEY) : S with type key = K.t = struct let acc = f acc k v in fold ~f ~x:acc r + let rec mapi ~f = function + | E -> E + | N (k, v, l, r, w) -> + N (k, f k v, mapi ~f l, mapi ~f r, w) + + let rec map ~f = function + | E -> E + | N (k, v, l, r, w) -> + N (k, f v, map ~f l, map ~f r, w) + let rec iter ~f m = match m with | E -> () | N (k, v, l, r, _) -> diff --git a/src/data/CCWBTree.mli b/src/data/CCWBTree.mli index f1f89065..a419de1b 100644 --- a/src/data/CCWBTree.mli +++ b/src/data/CCWBTree.mli @@ -62,6 +62,12 @@ module type S = sig val fold : f:('b -> key -> 'a -> 'b) -> x:'b -> 'a t -> 'b + val mapi : f:(key -> 'a -> 'b) -> 'a t -> 'b t + (** Map values, giving both key and value. Will use {!WORD.of_list} to rebuild keys. *) + + val map : f:('a -> 'b) -> 'a t -> 'b t + (** Map values, giving only the value. *) + val iter : f:(key -> 'a -> unit) -> 'a t -> unit val split : key -> 'a t -> 'a t * 'a option * 'a t From de2244641b04a2c40488a7d4a630780afcf11f7b Mon Sep 17 00:00:00 2001 From: jkloos Date: Tue, 5 Apr 2016 16:39:05 +0200 Subject: [PATCH 2/3] Added tests. --- src/data/CCTrie.ml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/data/CCTrie.ml b/src/data/CCTrie.ml index c161c7d7..6e9790bc 100644 --- a/src/data/CCTrie.ml +++ b/src/data/CCTrie.ml @@ -362,6 +362,7 @@ module Make(W : WORD) = struct T.fold (fun acc k v -> (k,v) :: acc) [] t1 \ |> List.sort Pervasives.compare = List.sort Pervasives.compare l1 *) + let mapi f t = let rec map_ prefix t = match t with | Empty -> Empty @@ -377,6 +378,11 @@ module Make(W : WORD) = struct map in Node (v', map') in map_ _id t + (*$T + T.mapi (fun k v -> v ^ "!") t1 \ + |> T.to_list |> List.sort Pervasives.compare =\ + List.map (fun (k, v) -> (k, v ^ "!")) l1 |> List.sort Pervasives.compare + *) let map f t = let rec map_ = function @@ -389,6 +395,12 @@ module Make(W : WORD) = struct in let map' = M.map map_ map in Node (v', map') in map_ t + (*$T + T.map (fun v -> v ^ "!") t1 \ + |> T.to_list |> List.sort Pervasives.compare =\ + List.map (fun (k, v) -> (k, v ^ "!")) l1 |> List.sort Pervasives.compare + *) + let iter f t = _fold From ec3c8819397e7357a577abedaf77cba509f829f9 Mon Sep 17 00:00:00 2001 From: jkloos Date: Tue, 5 Apr 2016 17:55:36 +0200 Subject: [PATCH 3/3] Added @since tags. --- src/data/CCIntMap.mli | 2 ++ src/data/CCTrie.mli | 8 ++++++-- src/data/CCWBTree.mli | 8 ++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/data/CCIntMap.mli b/src/data/CCIntMap.mli index c4a7901d..b0f7938f 100644 --- a/src/data/CCIntMap.mli +++ b/src/data/CCIntMap.mli @@ -67,8 +67,10 @@ val iter : (int -> 'a -> unit) -> 'a t -> unit val fold : (int -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t +(** @since NEXT_RELEASE *) val map : ('a -> 'b) -> 'a t -> 'b t +(** @since NEXT_RELEASE *) val choose : 'a t -> (int * 'a) option diff --git a/src/data/CCTrie.mli b/src/data/CCTrie.mli index 5c49c1a5..5bbd8333 100644 --- a/src/data/CCTrie.mli +++ b/src/data/CCTrie.mli @@ -76,10 +76,14 @@ module type S = sig (** Fold on key/value bindings. Will use {!WORD.of_list} to rebuild keys. *) val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t - (** Map values, giving both key and value. Will use {!WORD.of_list} to rebuild keys. *) + (** Map values, giving both key and value. Will use {!WORD.of_list} to rebuild keys. + @since NEXT_RELEASE + *) val map : ('a -> 'b) -> 'a t -> 'b t - (** Map values, giving only the value. *) + (** Map values, giving only the value. + @since NEXT_RELEASE + *) val iter : (key -> 'a -> unit) -> 'a t -> unit (** Same as {!fold}, but for effectful functions *) diff --git a/src/data/CCWBTree.mli b/src/data/CCWBTree.mli index a419de1b..8e64e08b 100644 --- a/src/data/CCWBTree.mli +++ b/src/data/CCWBTree.mli @@ -63,10 +63,14 @@ module type S = sig val fold : f:('b -> key -> 'a -> 'b) -> x:'b -> 'a t -> 'b val mapi : f:(key -> 'a -> 'b) -> 'a t -> 'b t - (** Map values, giving both key and value. Will use {!WORD.of_list} to rebuild keys. *) + (** Map values, giving both key and value. Will use {!WORD.of_list} to rebuild keys. + @since NEXT_RELEASE + *) val map : f:('a -> 'b) -> 'a t -> 'b t - (** Map values, giving only the value. *) + (** Map values, giving only the value. + @since NEXT_RELEASE + *) val iter : f:(key -> 'a -> unit) -> 'a t -> unit