Это еще один экземпляр ограничений let
-полиморфизма, что препятствует использованию полиморфной рекурсивной функции. Поскольку, OCaml 3.12, мы имеем explicit way, чтобы объявить, что ваша функция полиморфна.
Ваш случай немного сложнее, поскольку у вас есть неявная переменная типа, которая встречается внутри полиморфного типа row. Может быть, есть лучший способ, но мой подход, чтобы сделать этот тип переменным явно со следующего определением типа
type 'a t = 'a constraint 'a = [< `A | `B]
С таким удобным типом, легко написать правильную аннотацию для функции:
let rec f : 'a . 'a t -> int = function
| `A -> 0
| `B -> let _ = f `A in 1
только в том случае, если вы не хотите подвергать эту 'a t
, это нормально, так как вы не требуется, 'a t
равно [< 'A | 'B]
он просто делает 'a
тип переменной явно:
module M : sig
val f : [< `A | `B] -> int
end = struct
let rec f : 'a . 'a t -> int = function
| `A -> 0
| `B -> let _ = f `A in 1
end;;
Без введения 'a t
типа, вы можете сделать это с немного уродливой (но это, конечно, дело вкуса) обозначения:
let rec f : 'a . ([< `A | `B] as 'a) -> int = function
| `A -> 0
| `B -> let _ = f `A in 1
Конечно, это не будет масштабироваться, для нетривиальных типов.
Почему этот тип проблемы? – Drup
@Drup Я хочу передать значения типа '['B]' в 'f'. Я знаю, что могу передавать значения типа '[> 'B]', но это избавит от статических гарантий печати моего другого кода. – Halst