2013-07-03 2 views
1

Я почесал голову, чтобы выяснить подпись этой функцииКак определяется тип этой функции?

let make_rec f_norec = 
    let rec f x = f_norec f x in 
    f 

, который должен быть

val make_rec : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>.

Обратите внимание, что существует странное рекурсивное определение. Определенно, мне не хватает знаний. Может ли кто-нибудь показать мне, как вычислить тип функции (как это делает система вывода типов)?

Большое спасибо.

ответ

6

Начиная с внутренними из них, и работа наружу:

  1. будем называть тип xa
  2. затем f имеет тип a -> b где b является тип результата f
  3. f_norec принимает f и x, и он должен возвращать тот же тип, что и f, следовательно (a->b) -> a -> b
  4. make_rec принимает f_norec, и он возвращает f. Следовательно, ((a->b)->a->b) -> (a->b). По синтаксическим причинам последнюю пару круглых скобок можно опустить.
+0

Большое спасибо. Это довольно педагогично. – tfboy

+0

Что я не понимаю, почему последнюю пару круглых скобок можно опустить? – Indicator

+0

@Indicator. Как работает оператор right associative ->, и это делается так, потому что, если у вас есть функция 'f :: a -> b -> c', это означает, что если вы укажете только аргумент a , вы получаете функцию 'b -> c'. Это карри. OTOH, если тип '(a -> b) -> c', это означает, что у вас есть одна функция аргумента, которая принимает другую функцию' a -> b' и возвращает 'c'. – Ingo

Смежные вопросы