2015-01-05 3 views
2

유형 감시의 쌍과 목격 유형의 값에 대한 범용 컨테이너를 구축하고 있습니다. 이것은 여러 유형에 사용하기를 원합니다. 유형이 모두 동일하기 때문에 오류가 발생합니다. OCaml : "그 종류가 다릅니다"로 유형 이름 바꾸기가 실패하는 이유

그래서 나는이 같은 펑터의 결과에 유형의 이름을 변경하기 위해 노력하고있어 :

module type Witness = sig type 'a key type 'a value end 

module type Witnessed = sig 
    type 'a key 
    type 'a value 
    type t 
    type ('a, 'b) conv = { 
    key : 'c . 'c key -> 'a; 
    value : 'c . 'c value -> 'b; 
    } 
    val box : 'a key -> 'a value -> t 
    val conv : ('a, 'b) conv -> t -> ('a * 'b) 
end 

module MAKE(W : Witness) : Witnessed with type 'a key = 'a W.key 
        and type 'a value = 'a W.value = struct 
    include W 

    type t = Box : 'a key * 'a value -> t 
    let box k v = Box (k, v) 
    type ('a, 'b) conv = { 
    key : 'c . 'c key -> 'a; 
    value : 'c . 'c value -> 'b; 
    } 
    let conv conv (Box (k, v)) = (conv.key k, conv.value v) 
end 

type _ token 
type _ attrib 

module W = struct 
    type 'a key = 'a token 
    type 'a value = 'a attrib 
end 

module Boxed = struct 
    module T = MAKE(W) 
    type lexeme = T.t 
    type ('a, 'b) lexeme_conv = ('a, 'b) T.conv 
    include (T : module type of T with type 'a key := 'a token 
            and type 'a value := 'a attrib 
            and type t := lexeme 
            and type ('a, 'b) conv := ('a, 'b) lexeme_conv) 
end 

및 OCaml의 말한다 :

File "foo.ml", line 49, characters 38-80: 
Error: This variant or record definition does not match that of type 
     ('a, 'b) lexeme_conv 
     Their kinds differ. 

어떻게 전환의 유형과 다를 lexeme_conv 수 있습니까?

답변

4

는 다음과 같은 방법으로 lexeme_conv의 정의를 교체하여 문제를 해결할 수 있습니다 :이 유형의 별칭과 유형 정의가 파괴 교체에 관해서 같은 방식으로 행동하지 않는다는 사실에 기인한다

type ('a, 'b) lexeme_conv = ('a, 'b) T.conv = { 
    key : 'c . 'c T.key -> 'a; 
    value : 'c . 'c T.value -> 'b; 
} 

. 예를 들어, lexeme_conv가 별칭 인 경우 (레코드 정의가 노출되지 않기 때문에) 서명이 변경되며 이는 금지됩니다.

관련 문제