我很想知道爲什麼會發生此錯誤,以及哪種方法是解決此問題的最佳方法。錯誤:無法安全地評估遞歸定義模塊的定義
我有幾個文件types.ml
和types.mli
它定義一個變量類型value
,可以有多種不同的內置OCaml的類型(浮動,INT,列表,地圖,設置,等等)的。
因爲我必須在這個變體類型上使用std-lib,所以我需要通過仿函數具體化Set模塊,以便能夠通過定義ValueSet
模塊來使用value
類型的集合。
最後.ml
文件是一樣的東西:
module rec I :
sig
type value =
Nil
| Int of int
| Float of float
| Complex of Complex.t
| String of string
| List of (value list) ref
| Array of value array
| Map of (value, value) Hashtbl.t
| Set of ValueSet.t ref
| Stack of value Stack.t
...
type t = value
val compare : t -> t -> int
end
= struct
(* same variant type *)
and string_value v =
match v with
(* other cases *)
| Set l -> sprintf "{%s} : set" (ValueSet.fold (fun i v -> v^(string_value i)^" ") !l "")
end
and OrderedValue :
sig
type t = I.value
val compare : t -> t -> int
end
= struct
type t = I.value
let compare = Pervasives.compare
end
and ValueSet : Set.S with type elt = I.value = Set.Make(I)
正如你看到的,我不得不從定義函子的ValueSet
模塊能夠使用該數據類型。當我想在I
聲明中使用該模塊時,會出現問題。因此,我獲得以下錯誤:
Error: Cannot safely evaluate the definition of the recursively-defined module I
爲什麼會發生這種情況?哪種解決方法是一個好方法?只是要知道,我的方法是什麼,我試圖做的是正確的?除此之外,它按預期工作(我可以在其他模塊中將ValueSet類型與我的操作一起使用,但我必須對types.ml
中涉及的行進行註釋以通過編譯階段)。
我試圖刪除所有多餘的代碼,減少代碼必不可少的需要調查這個錯誤..如果它沒有足夠多隻問:)
編輯:根據OCaml的參考,我們有
Currently, the compiler requires that all dependency cycles between the recursively-defined module identifiers go through at least one 「safe」 module. A module is 「safe」 if all value definitions that it contains have function types typexpr1 -> typexpr2.
這一切,我發現,到目前爲止,但我沒有得到確切的意思..
預先感謝
是的,這是一個錯誤,而減少(這是一個'類型...和值=',但我刪除了其他類型)。其實沒有其他區別,只是檢查,所以我真的不知道是什麼原因導致了這個錯誤。我會更好地檢查並讓你知道,同時謝謝。 – Jack 2010-11-21 19:10:29
好的,我嘗試了頂層內'types.ml'的完整代碼,它不起作用,給出了相同的錯誤'錯誤:無法安全地評估遞歸定義模塊I的定義......這很愚蠢。雖然你的減少版本的作品,但如果我只是評論那一行還礦工.. – Jack 2010-11-21 19:28:10
這很可能是吉爾斯定義的問題;通過將任何常數值轉換爲單位功能確保模塊安全。 – nlucaroni 2010-11-22 20:11:52