Commit 643e4c0f authored by Andrei Paskevich's avatar Andrei Paskevich Committed by François Bobot
Browse files

Stdlib.Map: add map_filter, mapi_filter, mapi_filter_fold

cherry-pick from andrei's commit

Conflicts:

	src/util/stdlib.ml
	src/util/stdlib.mli
parent 65feefa1
......@@ -59,9 +59,13 @@ module type S =
val submap : (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool
val find_default : key -> 'a -> 'a t -> 'a
val find_option : key -> 'a t -> 'a option
val map_filter: ('a -> 'b option) -> 'a t -> 'b t
val mapi_filter: (key -> 'a -> 'b option) -> 'a t -> 'b t
val mapi_fold:
(key -> 'a -> 'acc -> 'acc * 'b) -> 'a t -> 'acc -> 'acc * 'b t
val translate : (key -> key) -> 'a t -> 'a t
val mapi_filter_fold:
(key -> 'a -> 'acc -> 'acc * 'b option) -> 'a t -> 'acc -> 'acc * 'b t
val add_new : key -> 'a -> exn -> 'a t -> 'a t
module type Set =
......@@ -205,6 +209,8 @@ module Make(Ord: OrderedType) = struct
let (x, d) = min_binding t2 in
bal t1 x d (remove_min_binding t2)
let merge_bal = merge
let rec remove x = function
Empty ->
Empty
......@@ -386,7 +392,7 @@ module Make(Ord: OrderedType) = struct
if c = 0 then
(* concat or bal *)
match f (Some d) with
| None -> concat l r
| None -> merge_bal l r
| Some d -> Node(l, x, d, r, h)
else if c < 0 then
bal (change x f l) v d r
......@@ -472,6 +478,15 @@ module Make(Ord: OrderedType) = struct
if c = 0 then Some d
else find_option x (if c < 0 then l else r)
let rec map_filter f = function
Empty -> Empty
| Node(l, v, d, r, _h) ->
concat_or_join (map_filter f l) v (f d) (map_filter f r)
let rec mapi_filter f = function
Empty -> Empty
| Node(l, v, d, r, _h) ->
concat_or_join (mapi_filter f l) v (f v d) (mapi_filter f r)
let rec mapi_fold f m acc =
match m with
......@@ -482,6 +497,7 @@ module Make(Ord: OrderedType) = struct
let acc,r' = mapi_fold f r acc in
acc,Node(l', v, d', r', h)
let translate f m =
let rec aux last = function
| Empty -> Empty,last
......@@ -498,6 +514,15 @@ module Make(Ord: OrderedType) = struct
Node(l,v,d,r,h),last in
let m,_ = aux None m in m
let rec mapi_filter_fold f m acc =
match m with
Empty -> acc, Empty
| Node(l, v, d, r, _h) ->
let acc,l' = mapi_filter_fold f l acc in
let acc,d' = f v d acc in
let acc,r' = mapi_filter_fold f r acc in
acc, concat_or_join l' v d' r'
let add_new x v e m = change x (function
| Some _ -> raise e
| None -> Some v) m
......
......@@ -216,8 +216,14 @@ module type S =
(** [find_default x d m] returns the [Some] of the current binding
of [x] in [m], or return [None] if no such binding exists. *)
val map_filter: ('a -> 'b option) -> 'a t -> 'b t
(** Same as {!Map.S.map}, but may remove bindings. *)
val mapi_filter: (key -> 'a -> 'b option) -> 'a t -> 'b t
(** Same as {!Map.S.mapi}, but may remove bindings. *)
val mapi_fold:
(key -> 'a -> 'acc -> 'acc * 'b)-> 'a t -> 'acc -> 'acc * 'b t
(key -> 'a -> 'acc -> 'acc * 'b) -> 'a t -> 'acc -> 'acc * 'b t
(** fold and map at the same time *)
val translate : (key -> key) -> 'a t -> 'a t
......@@ -225,6 +231,11 @@ module type S =
function [f]. [f] must be strictly monotone on the key of [m].
Otherwise it raises invalid_arg *)
val mapi_filter_fold:
(key -> 'a -> 'acc -> 'acc * 'b option) -> 'a t -> 'acc -> 'acc * 'b t
(** Same as {!Map.S.mapi_fold}, but may remove bindings. *)
val add_new : key -> 'a -> exn -> 'a t -> 'a t
(** [add_new x v e m] binds [x] to [v] in [m] if [x] is not bound,
and raises [exn] otherwise. *)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment