2009-09-20 5 views
16

OCaml을 사용하여 데이터 세트를 생성하고 이들 사이를 비교하려고합니다. Set.OrderType, Set.Make 등의 모듈 유형에 대한 설명서를 보았지만 세트를 초기화하거나 달리 사용하는 방법을 알 수 없습니다.OCaml : 모듈을 설정하십시오.

답변

28

세트는 재미있는 인터페이스를 사용하여 정의됩니다. 주어진 유형에 대해 Set.Make 펑터를 사용하여 해당 유형의 Set 모듈을 만들어야합니다. 표준 라이브러리에 대한 불행한 감독은 기본 유형에 Set 인스턴스를 정의하지 않는다는 것입니다. 대부분의 간단한 경우에는 Pervasives.compare을 사용하면 충분합니다. 여기 int 작동 정의는 다음과 같습니다

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

모듈 IntSetSet.S 인터페이스를 구현합니다. 이제 IntSet 모듈을 사용하여 세트에서 작동 할 수 있습니다 : 당신이 명시 적으로 OrderedTypeSet.Make의 입력 구조를 정의 할 필요가 없습니다

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

참고; 타입 유추가 당신을 위해 일을 할 것입니다. 당신은 펑터를 사용하여 몇 가지들이 generic을 잃게

module IntMap = Map.Make(IntOrder) 

때문이 당신이 Map의 인스턴스를 같은 모듈을 다시 사용할 수있는 장점이있다

module IntOrder : Set.OrderedType = struct 
    type t = int 
    let compare = Pervasives.compare 
end 

module IntSet = Set.Make(IntOrder) 

: 다른 방법으로는 다음과 같은 정의를 사용할 수 있습니다 요소의 유형은 고정되어 있습니다. 예를 들어 임의의 형식의 Set을 사용하는 함수를 정의 할 수 없으며 일부 연산을 수행합니다. 다행히도 Set 모듈은 Set에 많은 유용한 연산을 선언합니다.

+1

"임의의 유형의 세트를 사용하는 함수를 정의 할 수 없습니다" 그러나 특정 Set 모듈을 매개 변수로 사용하는 Functor 내부에서 함수를 정의하여 동일한 작업을 수행 할 수 있습니다. 하지만 프로그래머가이 펑터를 사용하여 또 다른 모듈을 만들어야하므로 물론 사용하기에 덜 편리합니다. – newacct

+0

오른쪽. 그것은 펑터 (functor)입니다. –

9

Chris의 답변 외에도 일부 표준 라이브러리 모듈은 이미 OrderedType 서명을 준수한다고 말할 수 있습니다. 예를 들어 다음과 같이 간단히 할 수 있습니다.

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 *) 

등등.

다음은 StringSet의 간단한 사용 예입니다. 세트가 기능적인 데이터 구조이므로 새로운 세트를 세트에 추가하면 새로운 세트가 리턴됩니다.

let set = List.fold_right StringSet.add ["foo";"bar";"baz"] StringSet.empty ;; 
StringSet.mem "bar" set ;; (* returns true *) 
StringSet.mem "zzz" set ;; (* returns false *)