Skyb0rg

Untitled

Jan 22nd, 2021 (edited)
949
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. type ELEM = sig
  2.     type t
  3.     val compare : t * t -> order
  4. end
  5.  
  6. type SET = sig
  7.     type t
  8.     type elem
  9.     val empty : t
  10.     val insert : elem * t -> t
  11.     val member : elem * t -> bool
  12. end
  13.  
  14. val Set = struct
  15.     (* Maybe the arguments don't need to be annotated so long as all module definitions are monomorphic.
  16.      * Because (Elem : ELEM where type = 'a) ~~ { compare : 'a * 'a -> order }
  17.      * It doesn't hurt though since functor arguments have to be annotated anyway.
  18.      *)
  19.     fun Make (Elem : ELEM where type t = 'a) : SET where type elem = 'a = struct
  20.         type t = Elem.t list
  21.         type elem = Elem.t
  22.         val empty = []
  23.         val insert = op ::
  24.         fun member (x, s) = List.exists (fn y => Elem.compare (x, y) = EQUAL) s
  25.     end
  26.     (* I'd love the following, but it may break type inference.
  27.      * Perhaps it would be OK since I don't use '.' in the function definition (?).
  28.      * fun MakeTuple Elem1 Elem2 = (Make Elem1, Make Elem2)
  29.      *)
  30.     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)
  31. end
  32.  
  33. val IntElem = struct type t = int; val compare = Int.compare end;
  34. val StringElem = struct type t = string; val compare = String.compare end;
  35. val (IntSet, StringSet) = Set.MakeTuple IntElem StringElem
  36.  
  37. val _ : IntSet.t = IntSet.insert (12, IntSet.empty)
  38. val _ : StringSet.t = StringSet.insert ("asdf", StringSet.empty)
  39.  
RAW Paste Data