2014-12-04 6 views
3

이 프로그램을 컴파일 :유형 공유 - typechecker 오류

module type Inc = 
    sig 
     type t 
     val inc : t -> t 
    end 

module type Dec = 
    sig 
     type t 
     val dec : t -> t 
    end 

module Merger (I : Inc) (D : Dec with type t = I.t) = 
    struct 
     let merge x = x |> I.inc |> D.dec 
    end 

module IntInc : Inc = 
    struct 
     type t = int 
     let inc x = x + 10 
    end 

module IntDec : Dec = 
    struct 
     type t = int 
     let dec x = x - 8 
    end 

module Combiner = Merger (IntInc) (IntDec) 

나는 다음과 같은 오류 얻을 :

File "simple.ml", line 30, characters 35-41: 
Error: Signature mismatch: 
     Modules do not match: 
     sig type t = IntDec.t val dec : t -> t end 
     is not included in 
     sig type t = IntInc.t val dec : t -> t end 
     Type declarations do not match: 
     type t = IntDec.t 
     is not included in 
     type t = IntInc.t 
     File "simple.ml", line 13, characters 38-50: Expected declaration 
     File "simple.ml", line 9, characters 13-14: Actual declaration 

내가 D : Dec with type t = I.t 제약이 D.t = I.t을 보장한다고 생각합니다. 왜 그렇지 않은가?

더 재미있는 것은 module Combiner = Merger (IntInc) (IntDec) 행을 제거하면 오류없이 컴파일됩니다.

제 질문은 : 내가 뭘 잘못하고있는거야?

답변

5

제약 조건이있는 Merger의 정의가 완전히 정확합니다. 따라서이 부분이 오류없이 컴파일됩니다.

당신이 말했듯이, 컴파일하지 않는 유일한 부분은 module Combiner = Merger (IntInc) (IntDec)입니다. 이는 OCaml이 알고있는 한 IntInt.t = IntDec.t 제약 조건을 충족시키지 않기 때문입니다. 그 이유는 OCaml이 IntInt.tIntDec.tint이라는 것을 모르기 때문입니다. 알고있는 것은 IntInt : IncIntDec : Dec입니다. 그 외 모든 것은 모듈의 개인 정보입니다.

당신이 Merger의 제약 조건을 해석 할 때 OCaml의 해당 정보를 사용할 수 있도록 개인 세부 사항보다는 유형 t에게 모듈의 공용 인터페이스의 일부를 만들고, IntInt : (Inc with type t = int)IntDec : (Dec with type t = int)에 모듈의 헤더를 변경할 수 있습니다이 문제를 해결하려면 펑터.

+0

위대한 설명, 고마워. – KCH