diff --git a/src/data/CCMixmap.ml b/src/data/CCMixmap.ml index 110261b2..2373cd75 100644 --- a/src/data/CCMixmap.ml +++ b/src/data/CCMixmap.ml @@ -3,6 +3,28 @@ (** {1 Maps with Heterogeneous Values} *) +(*$R + let module M = CCMixmap.Make(CCInt) in + + let inj_int = CCMixmap.create_inj() in + let inj_str = CCMixmap.create_inj() in + let inj_list_int = CCMixmap.create_inj() in + + let m = + M.empty + |> M.add ~inj:inj_int 1 1 + |> M.add ~inj:inj_str 2 "2" + |> M.add ~inj:inj_list_int 3 [3;3;3] + in + + assert_equal (M.get ~inj:inj_int 1 m) (Some 1) ; + assert_equal (M.get ~inj:inj_str 1 m) None ; + assert_equal (M.get ~inj:inj_str 2 m) (Some "2") ; + assert_equal (M.get ~inj:inj_int 2 m) None ; + assert_equal (M.get ~inj:inj_list_int 3 m) (Some [3;3;3]) ; + assert_equal (M.get ~inj:inj_str 3 m) None ; +*) + type 'b injection = { get : (unit -> unit) -> 'b option; set : 'b -> (unit -> unit); @@ -28,14 +50,14 @@ module type S = sig val empty : t (** Empty map *) - val get : inj:'a injection -> t -> key -> 'a option + val get : inj:'a injection -> key -> t -> 'a option (** Get the value corresponding to this key, if it exists and belongs to the same key *) - val add : inj:'a injection -> t -> key -> 'a -> t + val add : inj:'a injection -> key -> 'a -> t -> t (** Bind the key to the value, using [inj] *) - val find : inj:'a injection -> t -> key -> 'a + val find : inj:'a injection -> key -> t -> 'a (** Find the value for the given key, which must be of the right type. @raise Not_found if either the key is not found, or if its value doesn't belong to the right type *) @@ -43,10 +65,10 @@ module type S = sig val cardinal : t -> int (** Number of bindings *) - val remove : t -> key -> t + val remove : key -> t -> t (** Remove the binding for this key *) - val mem : inj:_ injection-> t -> key -> bool + val mem : inj:_ injection-> key -> t -> bool (** Is the given key in the map, with the right type? *) val iter_keys : f:(key -> unit) -> t -> unit @@ -85,23 +107,23 @@ module Make(X : ORD) : S with type key = X.t = struct let empty = M.empty - let find ~inj map x = + let find ~inj x map = match inj.get (M.find x map) with | None -> raise Not_found | Some v -> v - let get ~inj map x = + let get ~inj x map = try inj.get (M.find x map) with Not_found -> None - let add ~inj map x y = + let add ~inj x y map = M.add x (inj.set y) map let cardinal = M.cardinal - let remove map x = M.remove x map + let remove = M.remove - let mem ~inj map x = + let mem ~inj x map = try inj.get (M.find x map) <> None with Not_found -> false diff --git a/src/data/CCMixmap.mli b/src/data/CCMixmap.mli index 6499ce36..4885dcb3 100644 --- a/src/data/CCMixmap.mli +++ b/src/data/CCMixmap.mli @@ -3,9 +3,32 @@ (** {1 Maps with Heterogeneous Values} -{b status: experimental} + {b status: experimental} -@since 0.9 *) + {[ + module M = CCMixmap.Make(CCInt) + + let inj_int = CCMixmap.create_inj() + let inj_str = CCMixmap.create_inj() + let inj_list_int = CCMixmap.create_inj() + + let m = + M.empty + |> M.add ~inj:inj_int 1 1 + |> M.add ~inj:inj_str 2 "2" + |> M.add ~inj:inj_list_int 3 [3;3;3] + + assert (M.get ~inj:inj_int 1 m = Some 1) + assert (M.get ~inj:inj_str 1 m = None) + assert (M.get ~inj:inj_str 2 m = Some "2") + assert (M.get ~inj:inj_int 2 m = None) + assert (M.get ~inj:inj_list_int 3 m = Some [3;3;3]) + assert (M.get ~inj:inj_str 3 m = None) + ]} + + @since 0.9 + @since NEXT_RELEASE change of API, the map is last argument to + make piping with [|>] easier. *) type 'a injection (** An accessor for values of type 'a in any map. Values put @@ -28,14 +51,14 @@ module type S = sig val empty : t (** Empty map *) - val get : inj:'a injection -> t -> key -> 'a option + val get : inj:'a injection -> key -> t -> 'a option (** Get the value corresponding to this key, if it exists and belongs to the same key *) - val add : inj:'a injection -> t -> key -> 'a -> t + val add : inj:'a injection -> key -> 'a -> t -> t (** Bind the key to the value, using [inj] *) - val find : inj:'a injection -> t -> key -> 'a + val find : inj:'a injection -> key -> t -> 'a (** Find the value for the given key, which must be of the right type. @raise Not_found if either the key is not found, or if its value doesn't belong to the right type *) @@ -43,10 +66,10 @@ module type S = sig val cardinal : t -> int (** Number of bindings *) - val remove : t -> key -> t + val remove : key -> t -> t (** Remove the binding for this key *) - val mem : inj:_ injection-> t -> key -> bool + val mem : inj:_ injection-> key -> t -> bool (** Is the given key in the map, with the right type? *) val iter_keys : f:(key -> unit) -> t -> unit