問題爲什麼編譯器將不同名稱的泛型類型變量的兩個等價簽名標識爲不同的類型?
爲什麼
val of_bindings : (key * '_a) list -> '_a t
val of_bindings : (key * 'a) list -> 'a t
不同的簽名?
語境
我有一些地圖擴展實現:
MAPEXT.ml:
module type T = sig
include Map.S
val of_bindings : (key * 'a) list -> 'a t
end
mapExt.mli:
module Make (Key : Map.OrderedType)
: MAPEXT.T with type key = Key.t
mapExt.ml:
module Make (Key : Map.OrderedType) = struct
include Map.Make (Key)
let of_bindings =
let rec of_bindings acc =
function | (k, v) :: t -> of_bindings (add k v acc) t
| [] -> acc in
of_bindings empty
end
編譯器給了我一個錯誤的 ocamlopt -c MAPEXT.ml mapExt.mli mapExt.ml
Error: The implementation mapExt.ml does not match the interface mapExt.cmi: ... At position module Make(Key) : Values do not match: val of_bindings : (key * '_a) list -> '_a t is not included in val of_bindings : (key * 'a) list -> 'a t File "mapExt.ml"
結果我以爲泛型類型變量的名稱並不重要,只是信號不同類型。但從我現在看到的他們似乎有不同的含義。
如何避免這個問題來編譯這段代碼?
相關:What is the difference between 'a and '_l?
請閱讀「通過部分應用程序獲得的函數不夠多態」以及https://ocaml.org/learn/faq.html#Typing – camlspotter