Я хотел бы написать катаморфизм в OCaml для любого эндофунктора (в терминах типов) как функтора (в терминах OCaml):
module type Functor = sig
type 'a t
(* ... *)
end
module Make(F : Functor) = struct
type fix_t = 'a F.t as 'a
(* ... *)
end
Но этот код выдает ошибку: «Переменная типа a встречается внутри F.t».
Я знаю, что для компилятора OCaml существует флаг «-recttypes», и вместо fix_t
принимается следующее определение типа: type fix_list = 'a list as 'a
.
Поэтому я думаю, что ошибка вызвана неизвестным типом t
, но мне кажется странным, что здесь программа проверки типов различает известные и неизвестные типы.
Даже с -rectypes
рекурсивные типы должны быть сжимающими: все рекурсивные переменные должны встречаться в качестве аргументов встроенных конструкторов типов или типов данных. Без этого ограничения уравнения вида
type 'a id = 'a
type t = 'a id as 'a
может быть принят и допускает несколько несравнимых решений (например, t=int
или t=float
).
Таким образом, проще избегать -rectypes
и использовать явный конструктор для защиты рекурсии:
type fix = Fix of fix t [@@unboxed]
Спасибо! Не могли бы вы добавить несколько ссылок, чтобы узнать больше о поведении компилятора?
Возможно, это потому, что
t
может быть определен какtype 'a t = 'a
, и в этом случаеfix_t
будет не правильным рекурсивным, а пустым типом.