Этот человек говорит: «Остерегайтесь, что такие функции, как ListLabels.fold_left, тип результата которых является типовой переменной, никогда не будут считаться полностью применимыми».
Вот что происходит в вашем примере. Остерегайтесь, это немного сложно.
# ListLabels.fold_left;;
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun>
это просто классическое использование: ListLabels.fold_left
принимает 3 аргумента, а именно функцию с меткой f
, инициализатор init
и список.
Сейчас в
let add = (+) and i = 0
in ListLabels.fold_left ~add ~i [1;2;3];;
заявка ListLabels.fold_left ~add ~i [1;2;3]
считается неполной (как говорит мужчина). Это означает, что `ListLabels.fold_left
сначала получает свой неименованный аргумент [1;2;3]
и возвращает функцию типа f:('a -> int -> 'a) -> init:'a -> 'a
. Назовем эту функцию foo.
Поскольку вы даете два именованных аргумента, помеченных add
и i
, тип 'a
считается функциональным типом типа add:'c -> ~i:'d -> 'e
.
В зависимости от типа переменных add
и i
тип 'c
должен быть int -> int -> int
, а 'd
должен быть int
.
Заменяя эти значения в типе 'a
, мы получаем, что тип 'a
равен add:(int -> int -> int) -> i:int -> 'e
. И заменив это в типе foo (я рад, что есть копипастинг ;-), его тип
f:((add:(int -> int -> int) -> i:int -> 'e)
-> int
-> (add:(int -> int -> int) -> i:int -> 'e))
-> init:(add:(int -> int -> int) -> i:int -> 'e)
-> (add:(int -> int -> int) -> i:int -> 'e)
Удалив ненужные скобки и преобразовав альфа (т.е. переименовав) 'e
в 'a
, мы получим
f:((add:(int -> int -> int) -> i:int -> 'a)
-> int
-> add:(int -> int -> int) -> i:int -> 'a)
-> init:(add:(int -> int -> int) -> i:int -> 'a)
-> add:(int -> int -> int) -> i:int -> 'a
Это тип foo. Но помните, что вы передаете в foo два аргумента, помеченных ~add
и ~i
. Таким образом, значение, которое вы получаете в конце, относится не к типу add:(int -> int -> int) -> i:int -> 'a
, а к типу 'a
. И весь тип вашего примера, возвращенный компилятором,
f:((add:(int -> int -> int) -> i:int -> 'a)
-> int
-> add:(int -> int -> int) -> i:int -> 'a)
-> init:(add:(int -> int -> int) -> i:int -> 'a)
-> 'a
person
jrouquie
schedule
06.08.2012