В чем разница между "а" и "_l"?
В чем разница между 'a
а также '_l
?
Я смотрел на эту ошибку и не мог ее понять:
Error: This expression has type ('a -> float polynomial) list but an expression was expected of type float polynomial list derivlist: ('_l → float polynomial) list
2 ответа
_
обозначает слабо полиморфную переменную: она находится в положении, когда ее нельзя обобщить.
В FAQ по OCaml есть два объяснения, связанных со слабым полиморфизмом: см . Функция, полученная в результате частичного применения, недостаточно полиморфна, и следующее.
Обычно это происходит, когда вы используете нелокальную ссылку (тип которой не может быть обобщен) или когда определяются полиморфные функции, которые не являются синтаксически функциями (они не начинаются с fun x -> ..
а скорее приложение функции). В некоторых случаях есть простое исправление (eta-расширение, см. 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, см. Статью "Расслабление ограничения значения " Жака Гаррига (2004).
В сообщении об ошибке от компилятора есть переменная слабого типа, но я не уверен, что слабая переменная связана с ошибкой (я не вижу, как состояние переменной типа могло быть причиной этого сообщения).
Вы уверены, что не определяете два типа polynomial
? Это вопрос чуть выше двух, указанных Гаше в его ответе в FAQ (" Сообщение об ошибке: тип не совместим с самим собой").