2013-07-03 3 views
1

Je me gratte la tête pour comprendre la signature de cette fonctionComment le type de cette fonction est-il déduit?

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

qui devrait être

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

Notez qu'il existe une définition récursive étrange. Certainement, je manque des connaissances là-bas. Quelqu'un peut-il me montrer comment calculer le type de la fonction (comme le fait le système d'inférence de type)?

Merci beaucoup.

Répondre

6

En commençant par les internes, et en travaillant vers l'extérieur:

  1. Appelons type de xa
  2. alors f est de type a -> bb est le type de résultat de f
  3. f_norec prend f et x et il doit retourner le même type que f, d'où (a->b) -> a -> b
  4. make_rec prend f_norec et renvoie f. Par conséquent ((a->b)->a->b) -> (a->b). Pour des raisons syntaxiques, la dernière paire de parenthèses peut être omise.
+0

Merci beaucoup. C'est très pédagogique. – tfboy

+0

Ce que je ne comprends pas, pourquoi la dernière paire de parenthèses peut être omise? – Indicator

+0

@Indicator Voici comment fonctionne le bon opérateur associatif ->, et c'est ainsi parce que si vous avez une fonction 'f :: a -> b -> c' alors cela signifie que si vous ne fournissez que l'argument a , vous obtenez une fonction 'b -> c'. C'est en cours. OTOH, si le type est '(a -> b) -> c' cela signifie que vous avez une fonction un argument qui prend une autre fonction' a -> b' et retourne un 'c'. – Ingo

Questions connexes