Почему этот слабо полиморфный тип?
module type M = sig
type ('k, 'v) t
val foo : 'k -> ('k, 'v) t
end
module M : M = struct
type ('k, 'v) t = ('k * 'v) list
let foo k = []
end
В этом небольшом примере, почему бы M.foo 123
имеют слабо полиморфный тип, (int, '_a) M.t)
?
1 ответ
Решение
Это ограничение стоимости, я считаю. M.foo 123
это не значение, это приложение-функция. Так что он не может иметь полностью полиморфный тип.
Вы можете исправить это, объявив 'v
быть ковариантным в вашем типе модуля. Я никогда лично не пробовал это раньше, но, похоже, это работает:
# module type M = sig
type ('k, +'v) t
val foo: 'k -> ('k, 'v) t
end;;
module type M = sig type ('k, +'v) t val foo : 'k -> ('k, 'v) t end
# module M: M = struct
type ('k, 'v) t = ('k * 'v) list
let foo k = []
end;;
module M : M
# M.foo 123;;
- : (int, 'a) M.t = <abstr>
Я считаю, что это работает из-за "смягченного ограничения ценностей".
Я узнал об этом использовании аннотации отклонений от @gasche здесь: Когда в OCaml вступает в действие ограничение по ослабленным значениям?