Ошибка: невозможно безопасно оценить определение рекурсивно определенного модуля

Мне любопытно понять, почему возникает эта ошибка и как ее лучше всего обойти .

У меня есть пара файлов types.ml и types.mli , которые определяют вариантный тип значение , который может иметь множество различных встроенных типов OCaml. (float, int, list, map, set и т. д.).

Поскольку я должен использовать std-lib вместо этого варианта типа, мне нужно было конкретизировать модуль Set через функтор, чтобы иметь возможность использовать наборы 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)

Как видите, мне пришлось определить модуль ValueSet из функтора, чтобы иметь возможность использовать этот тип данных. Проблема возникает, когда я хочу использовать этот модуль внутри объявления I . Итак, я получаю следующую ошибку:

Ошибка: Невозможно безопасно оценить определение рекурсивно определенного модуля I

Почему это происходит? Какой хороший способ решить эту проблему? И просто чтобы знать, правильный ли мой подход к тому, что я пытаюсь сделать? Кроме того, он работает по назначению (я могу использовать тип ValueSet с моими операциями в других модулях, но я должен прокомментировать соответствующую строку в types.ml , чтобы пройти этап компиляции).

Я попытался удалить весь лишний код и сократить код до необходимого для исследования этой ошибки ... если этого недостаточно, просто спросите:)

РЕДАКТИРОВАТЬ: согласно ссылке OCaml, у нас есть это

. В настоящее время компилятор требует, чтобы все циклы зависимости между рекурсивно определенными идентификаторами модулей проходили по крайней мере через один «безопасный» модуль. Модуль является «безопасным», если все содержащиеся в нем определения значений имеют типы функций typexpr1 -> typexpr2.

Это все, что я нашел до сих пор, но я не понимаю точного значения ..

Заранее благодарю

6
задан Jack 21 November 2010 в 20:52
поделиться