Reputation: 1491
I have implemented a representation of sets (balanced search trees) in OCaml. It's actually a functor Make
of signature
module Make :
functor (T : ORDERED_TYPE) ->
sig
type elt = T.t
type t
val empty : t
val cons : elt -> t -> t
val delete : elt -> t -> t
val mem : elt -> t -> bool
val cardinal : t -> int
end
where
module type ORDERED_TYPE = sig type t val compare : t -> t -> int end
Now I'd like to implement a dictionary like Map
in the standard library. It has to have a signature like
module Make: functor (T : ORDERED_TYPE) -> sig
type key = T.t
type +'a t
...
end
where t
is the type of dictionaries.
Implementing balanced search trees again is not elegant, so I want to define dictionaries in terms of sets implemented as a functor above. Can I do that?
Upvotes: 5
Views: 1280
Reputation: 1032
Well, there actually IS an equal operator in there -- the compare function from the ordered type.
So define your own module for a key/value type that only takes into comparison the key-part:
module Keyvalue = struct
type t = ('a * 'b)
let compare x y = Pervasives.compare (fst x) (fst y)
end
and you are done. The problem now is, that your Set does not allow you to get its values; there is no get nor a fold function -- which imho is really limiting for such a data structure. If you are allowed to fumble with the Set implementation, you need to add a get function:
module Set = sig
...
get : t -> elt -> elt
end
that will return the just asked for element. If you take the second element of the returned tuple, you have your value from the original key/value pair.
Upvotes: 0
Reputation: 36118
As others have already pointed out, there are at least two reasons why you cannot implement the requested map functor on top of the given set:
'a map
seems to require.Are you sure that the task requires you to implement maps on top of sets? Maybe you are just supposed to implement them like sets?
Upvotes: 2
Reputation: 31479
As Jeffrey noted, you Set
interface is not expressive enough to conveniently implement Map
on top of it. It would be simpler to implement Set
from Map
, by defining sets as maps from keys to unit value.
Another possibility, that I would recommend, is to first expose a module of balanced search trees with no encapsulation, with the sole purpose of providing an efficient data structure, that is entirely revealed by the interface. You are then free to reuse it for any data structure you like, including Map
and Set
, without having to play games to define one in term of the other. This may not be terribly important in this case (defining Set
from Map
is reasonable for most purposes), but is a better design in the general case, in my opinion.
In a nutshell: if you want to reuse implementations, then expose "implementation modules", and define your "interface modules" on top of them.
Upvotes: 4
Reputation: 66823
Seems to me a map is a (partial) function, which is a set of ordered pairs. If you define your comparison function correctly I think it can be done. You might have to add a function to the Set interface to account for the fact that two values can compare equal for purposes of membership but not actually be equal values. It doesn't seem possible to define the lookup function for the map with the current interface.
Upvotes: 3