_
обозначает слабо полиморфной переменной: она находится в положении, когда она не может быть обобщена.
Существует два объяснения, связанные со слабым полиморфизмом в FAQ OCaml: см. A function obtained through partial application is not polymorphic enough и следующий.
Это обычно происходит, если вы используете нелокальную ссылку (тип которой не может быть обобщен) или при определении полиморфных функций, которые не являются синтаксически функциями (они не начинаются с fun x -> ..
, а скорее являются прикладной функцией). В некоторых случаях есть простое исправление (eta-expansion, см. FAQ), иногда это не так, и иногда ваша программа была просто необоснованной.
Простой пример: let a = ref []
не получает полиморфный тип a list ref
. В противном случае вы можете использовать оба значения как int list
, так и bool list
и смешивать элементы разных типов, изменяя ссылку. Вместо этого он получает тип '_a list ref
. Это означает, что тип не является полиморфным, а просто неизвестен. Как только вы сделаете что-то с a
с определенным типом, он исправляет '_a
раз и навсегда.
# let a = ref [];;
val a : '_a list ref = {contents = []}
# let sum_of_a = List.fold_left (+) 0 !a;;
val sum_of_a : int = 0
# a;;
- : int list ref = {contents = []}
Для объяснения глубокого ограничения значения и ограничения «расслабленным» стоимость фактически реализованного в типе проверки OCaml см Relaxing the Value Restriction бумагу Жака Гаррик (2004).