Понимание сигнатур типов функций - PullRequest
0 голосов
/ 12 марта 2019

У меня проблемы с пониманием сигнатур типов функций для функций более высокого порядка в OCaml.

fun f -> f 3
(int -> a) -> a

Способ, которым я обрабатываю это, состоит в том, что часть f 3 принимает int в качестве ввода и возвращаеттип, определенный функцией f, которая обозначается как a.Так что на самом деле fun f это тип (int->a).Но тогда откуда взялись последние a в (int -> a) -> a?

Ответы [ 2 ]

5 голосов
/ 12 марта 2019

Ваш первый пример:

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

Надеюсь, это поможет прояснить ситуацию.

0 голосов
/ 15 марта 2019

Мы могли бы аннотировать анонимную функцию следующим образом:

fun (f : int -> 'a) -> (f 3 : 'a)

То есть, это функция от f : int -> 'a до 'a, так что отсюда ваш последний 'a.

...