Ваш первый пример:
fun f -> f 3
Я думаю, что одна из возможных путаниц, которые могут возникнуть у вас, заключается в том, что вы думаете об этом как об определении функции с именем f
. Это не вариант. Это анонимное значение, представляющее функцию, также известную как лямбда. f
представляет параметр этой анонимной функции.
Чтобы было яснее, давайте присвоим функции имя g
. Другими словами, предположим, что мы определяем g
следующим образом:
let g = fun f -> f 3
ОК, поэтому g
- это функция, которая принимает один параметр f
. Этот параметр f
явно является функцией, поскольку мы видим, что он применяется к 3. (То есть мы видим, что он вызывается с аргументом 3). Что возвращает g
? Он возвращает все, что f
возвращает при вызове, верно?
Поскольку g
является функцией, ее тип должен иметь вид:
d -> c
Т.е. он принимает что-то типа d
и возвращает что-то типа c
. Из приведенных выше соображений мы знаем, что d
является типом функции, и мы также знаем, что тип возвращаемого значения этой функции также является типом возврата g
. Так что если d
(более подробно) b -> a
, то полный тип g
будет выглядеть следующим образом:
(b -> a) -> a
Однако мы также знаем, что параметр функции f
принимает аргумент int, поскольку мы видим, что он применяется к 3. Таким образом, тип b
должен быть int
. Это дает нам следующее для типа g
:
(int -> a) -> a
Надеюсь, это поможет прояснить ситуацию.