OCaml: Set modules

前端 未结 2 734
执念已碎
执念已碎 2021-02-18 19:02

I want to use OCaml to generates sets of data and make comparisons between them. I have seen the documentation for Module types like Set.OrderType, Set.Make

相关标签:
2条回答
  • 2021-02-18 19:06

    In addition to Chris's answer, it may be useful to say that some standard library modules already adhere to the OrderedType signature. For example, you can simply do:

    module StringSet = Set.Make(String) ;;       (* sets of strings *)
    module Int64Set = Set.Make(Int64) ;;         (* sets of int64s *)
    module StringSetSet = Set.Make(StringSet) ;; (* sets of sets of strings *)
    

    And so on.

    Here's a simple usage example for StringSet; remember that sets are functional data structures, so adding a new element to a set returns a new set:

    let set = List.fold_right StringSet.add ["foo";"bar";"baz"] StringSet.empty ;;
    StringSet.mem "bar" set ;; (* returns true *)
    StringSet.mem "zzz" set ;; (* returns false *)
    
    0 讨论(0)
  • 2021-02-18 19:07

    Sets are defined using a functorial interface. For any given type, you have to create a Set module for that type using the Set.Make functor. An unfortunate oversight of the standard libraries is that they don't define Set instances for the built-in types. In most simple cases, it's sufficient to use Pervasives.compare. Here's a definition that works for int:

    module IntSet = Set.Make( 
      struct
        let compare = Pervasives.compare
        type t = int
      end )
    

    The module IntSet will implement the Set.S interface. Now you can operate on sets using the IntSet module:

    let s = IntSet.empty ;;
    let t = IntSet.add 1 s ;;
    let u = IntSet.add 2 s ;;
    let tu = IntSet.union t u ;;
    

    Note that you don't have to explicitly define the input structure for Set.Make as an OrderedType; type inference will do the work for you. Alternatively, you could use the following definition:

    module IntOrder : Set.OrderedType = struct
      type t = int
      let compare = Pervasives.compare
    end
    
    module IntSet = Set.Make( IntOrder )
    

    This has the advantage that you can re-use the same module to instantiate a Map:

    module IntMap = Map.Make( IntOrder )
    

    You lose some genericity in using functors, because the type of the elements is fixed. For example, you won't be able to define a function that takes a Set of some arbitrary type and performs some operation on it. (Luckily, the Set module itself declares many useful operations on Sets.)

    0 讨论(0)
提交回复
热议问题