Question

J'ai une question concernant deux types int -> (int -> int) et (int -> int) -> int. Quelle est la différence entre ces deux-là?

J'ai lu ici quelque part que le premier pourrait être interprété comme une fonction qui prend un INT et renvoie une fonction qui prend et INT et renvoie un int, qui est le même que int -> int -> int. Est-ce correct?

Était-ce utile?

La solution

La différence entre int -> (int -> int) et int -> int -> int est négligeable (vous ne vous soucieriez vraiment que si vous deviez vous interopérer avec une autre langue). Ce sont des fonctions au curry qui prennent efficacement deux entiers et renvoient un entier (par exemple, l'opérateur d'addition intégré a un type dans ce sens).

Cependant, ces deux sont très différents de (int -> int) -> int, qui prend un fonction Des entiers aux entiers et renvoie un entier. Comme d'autres l'ont mentionné, le seul exemple simple d'une telle fonction appliquerait la fonction donnée à une valeur spécifique (par exemple fun (f:int->int) -> f 13).

Autres conseils

Bonne question, je soupçonne que fonctionnellement il n'y a pas beaucoup de différence. J'ai passé un certain temps à jouer pour essayer de trouver comment même obtenir ces deux signatures. (John Palmer let fun1 i = fun j -> i + j donne juste int -> int -> int pour moi)

let add a b = a + b       // int -> int -> int
let inc a = add a         // int -> (int -> int)

Je ne pouvais pas penser à un exemple non contrôlé pour la deuxième signature:

let foo fn : int -> fn 1  // (int -> int) -> int

(Cela ne répond pas directement à votre question, mais peut donner à quelqu'un d'autre quelque chose à mâcher)

Je ne connais pas vraiment F #, mais cela semble assez intuitif (beaucoup d'autres langues ont les mêmes notions).

  1. Est une fonction qui prend un int, et renvoie une fonction qui prend un int et renvoie un int
  2. Est une fonction qui prend une fonction qui prend un int et renvoie un int, et renvoie un int

Le premier serait un peu comme une fonction au curry.

Voyons donc à quoi ressembleraient les implémentations:

première

let func1 i = fun j -> i+j

Cela a une signature de int -> (int -> int)

Notez que func1 2 3 ne devrait pas fonctionner

ÉDITER: Il s'avère qu'en raison de la façon dont l'association fonctionne, c'est en fait bien

Mais c'est différent de

let func2 i j= i+j

qui a un type de int -> int -> int

ici func2 1 2 c'est bien

L'autre exemple que nous pouvons créer comme ceci:

let func4 a = a 1

Cela aura une signature de ('t->int) -> u Choisir un béton a marchera. Notez que func4 1 2 ne compilera certainement pas

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top