Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- type ELEM = sig
- type t
- val compare : t * t -> order
- end
- type SET = sig
- type t
- type elem
- val empty : t
- val insert : elem * t -> t
- val member : elem * t -> bool
- end
- val Set = struct
- (* Maybe the arguments don't need to be annotated so long as all module definitions are monomorphic.
- * Because (Elem : ELEM where type = 'a) ~~ { compare : 'a * 'a -> order }
- * It doesn't hurt though since functor arguments have to be annotated anyway.
- *)
- fun Make (Elem : ELEM where type t = 'a) : SET where type elem = 'a = struct
- type t = Elem.t list
- type elem = Elem.t
- val empty = []
- val insert = op ::
- fun member (x, s) = List.exists (fn y => Elem.compare (x, y) = EQUAL) s
- end
- (* I'd love the following, but it may break type inference.
- * Perhaps it would be OK since I don't use '.' in the function definition (?).
- * fun MakeTuple Elem1 Elem2 = (Make Elem1, Make Elem2)
- *)
- fun MakeTuple (Elem1 : ELEM where type t = 'a) (Elem2 : ELEM where type t = 'b) : (SET where type elem = 'a) * (SET where type elem = 'b) = (Make Elem1, Make Elem2)
- end
- val IntElem = struct type t = int; val compare = Int.compare end;
- val StringElem = struct type t = string; val compare = String.compare end;
- val (IntSet, StringSet) = Set.MakeTuple IntElem StringElem
- val _ : IntSet.t = IntSet.insert (12, IntSet.empty)
- val _ : StringSet.t = StringSet.insert ("asdf", StringSet.empty)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement