Мне любопытно понять, почему возникает эта ошибка и как лучше всего ее обойти.
У меня есть пара файлов types.ml
и types.mli
, которые определяют тип варианта value
это может быть много разных встроенных типов OCaml (float, int, list, map, set и т. д.).
Так как мне нужно использовать std-lib над этим вариантом, мне нужно было конкретизироватьУстановите модуль через функтор, чтобы можно было использовать наборы типа value
, определив модуль ValueSet
.
Окончательный файл .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)
AsВы можете видеть, что я должен был определить модуль ValueSet
из функтора, чтобы иметь возможность использовать этот тип данных.Проблема возникает, когда я хочу использовать этот модуль внутри объявления I
.Чтобы я получил следующую ошибку:
Ошибка: невозможно безопасно оценить определение рекурсивно определенного модуля I
Почему это происходит?Какой хороший способ решить это?И просто чтобы знать, правильный ли мой подход к тому, что я пытаюсь сделать?Кроме того, он работает как задумано (я могу использовать тип ValueSet с моими операциями в других модулях, но я должен прокомментировать соответствующую строку в types.ml
, чтобы пройти этап компиляции).
Я пыталсяудалить весь лишний код и уменьшить его до необходимого для расследования этой ошибки .. если это не достаточно, просто спросите:)
РЕДАКТИРОВАТЬ: согласно ссылке OCaml, у нас есть
В настоящее время компилятор требует, чтобы все циклы зависимостей между рекурсивно определенными идентификаторами модуля проходили хотя бы один «безопасный» модуль.Модуль является «безопасным», если все определения значений, которые он содержит, имеют типы функций typexpr1 -> typexpr2.
Это все, что я нашел до сих пор, но я не понимаю точное значение ..
Спасибо заранее