2014-10-18 16 views
3

試圖編譯OCaml的仿函數取多態性變異型

module F (M : sig 
    type t = [> `Foo ] 
end) = struct 
    type t = [ M.t | `Bar ] 
end 

讓我

Error: A type variable is unbound in this type declaration. 
In type [> `Foo ] as 'a the variable 'a is unbound 

我在做什麼錯?

回答

4

type t = [> `Foo]無效,因爲[> `Foo]是一個開放的類型,並且隱含地包含一個類型變量。該定義被拒絕,就像下面的類型定義被拒絕,因爲RHS具有未在LHS量化類型變量:

type t = 'a list 

你必須要關閉它:

type t = [ `Foo ] 

或量化類型的變量:

type 'a t = [> `Foo] as 'a 

這相當於

type 'a t = 'a constraint 'a = [> `Foo] 
+0

我希望我的函數參數'M'能夠擴展'F.t',而其他變體沒有在簽名中指定;例如'type t = [\'Foo | \'巴茲]'。所以我不認爲封閉式會起作用。我試圖做甚至可能嗎? 另外,我不清楚爲什麼開放類型包含一個類型變量 - 你能解釋/鏈接到一個解釋? RWO似乎沒有提到任何有關隱式類型變量的內容。 – int3 2014-10-18 19:42:50

+0

''type t = [>'Baz | M.t]''是你想要的;這裏'M.t'可以關閉。 – camlspotter 2014-10-20 01:59:19

+0

請注意,我使用的「隱式類型變量」不是官方的OCaml單詞。在OCaml中,所有可實例化的對象都必須具有類型變量,包括開放多變類型''[>'A | 'B]''和打開的對象類型''。但是如果你不在別處使用它們,你可以省略寫它們。它們實際上是一種用約束編寫類型變量的簡短方法:'''約束'a = [>'A | 'B]''和''約束'爲'a = '。它們僅可實例化爲其約束的子類型。 (你也可以像''一樣'''''''''''''和''寫成等效的形式。) – camlspotter 2014-10-20 02:40:27