2011-01-20 4 views
9

OCaml에서 상호 재귀 적 모듈 정의를 사용할 때는 .ml 파일에서도 서명을해야합니다. 이것은 .mli에서 제공된 인터페이스를 공개하려는 성가신 일로, 서명을 두 번 반복합니다. :(!왜 OCaml에서 상호 재귀 적 모듈의 서명이 필요한가?

module rec Client : sig 
    type ('serv,'cli) t 

    (* functions ... *) 
end = struct 
    type ('serv,'cli) t = 
    { server: ('serv,'cli) Server.t 
    ; (* other members ... *) 
    } 
end 
and Server : sig 
    type ('serv,'cli) t 

    (* functions ... *) 
end = struct 
    type ('serv,'cli) t = 
    { mutable clients: ('serv,'cli) Client.t list 
    ; mutable state: 'serv 
    } 

    (* functions again ... *) 
end 

이 내가 뭘하는지의 대략적인 근사치 (Client 형 객체를 인스턴스화 Server 알고있다. Server의 자신의 Client의 알). 물론

, 서명은 . .mli 반복 왜 이런 일이 필요하다

(참고 :. 내가 불평 아니지만, 실제로는 유형 이론 또는 "하드 컴파일러 문제"이것에 대한 - 관련 이유가 있는지 알고 싶어)?

답변

4

내 생각 엔 재귀 모듈을 컴파일하려면 컴파일러가 구현을 위해 주석을 입력해야합니다. mli 파일 (사용하고있는 경우)에서는 이러한 모듈 유형을 더 제한하거나 숨길 수 있으므로 일반적으로 컴파일러가 유형 재귀를 해결할 때 유용한 유형을 찾기를 기대하는 것은 바람직하지 않습니다.

+0

그건 의미가 있습니다. 사실, 나는이 "feature"를'.mli'에서 외부 소비자들에게 다른 타입 시그니처를 노출시킴으로써 사용한다; 나는 깨달았어야했다. – Ashe

+1

좋은 추측입니다. 상호 회귀 적 모듈과 펑터의 경우 추론은 일반적으로 결정 불가능하기 때문에 유형 주석이 필요합니다. 이 문헌은 형식 시스템을 수정하여 최소한의 주석 요구 사항을 최적화하고 건전성을 유지하려는 시도로 가득합니다. 주석 요구 사항 부담을 줄이기 위해 OCaml의 형식 시스템을 개선 할 수 있는지 여부는 논쟁의 여지가있다. –

7

내가 아는 한,이 문제를 해결할 길이 없다. 컴파일러에 관한 한 매우 높은 수준에서 Client의 형식 시그니처는 Server의 형식 시그니처를 알 때까지 불완전합니다. 그 반대의 경우도 마찬가지입니다. 원칙적으로이 문제를 해결할 수있는 방법이 있습니다. 컴파일러는 컴파일 할 때 .mli 파일을 참조 할 수 있습니다. 하지만 이러한 접근 방식에는 단점이 있습니다. 컴파일러와 링커의 책임을 일부 혼합하여 모듈 컴파일 (말장난 없음)을 어렵게 만듭니다.

관심이 있으시면 재귀 모듈에 Xavier Leroy의 original proposal을 권장합니다.

+0

링크를 제공해 주셔서 감사합니다. 타입 이론은 나보다 약간 뛰어나지 만 여전히 좋은 읽을 거리입니다. 그러나 ygrek에서 언급했듯이 .mli가 실제 모듈 자체를 컴파일하는 데 사용되는 형식을 선언하는 것이 아닙니다. 당신이 언급 한 것처럼 그렇게하려고한다면 그것은 더 추악해질 것입니다. – Ashe