12
votes

F # Generics / Fonction Syntaxe de surcharge

Je suis confus sur la façon d'étiqueter une fonction comme générique sans déclaration de type explicite comme ('a ->' a) code> xxx pré>

ceci nous donne p> xxx pré>

Cependant, nous pouvons alors appeler immédiatement p> xxx pré>

et maintenant la valeur d'ajouter est p>

add 2 3 // then we get
error: This expression was expected to have type string but here has type int


1 commentaires

J'imagine que c'est un duplicata; Je serais très surpris si cela n'a pas été demandé auparavant. Mais c'est une excellente explication du problème.


3 Réponses :


2
votes

Si je vous comprends correctement, utilisez Inline: xxx

impression: xxx

link: http://ideone.com/awsyni


0 commentaires

2
votes

Faites-le Inline

let inline add a b = a + b
(*
val inline add :
  a: ^a -> b: ^b ->  ^c
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)
*)
add "Hello " "World!"
// val it : string = "Hello World!"
add 2 3
// val it : int = 5


0 commentaires

19
votes

Ceci est le squelette embarrassant de F # dans le placard.

Essayez ceci: xxx

entièrement générique! Clairement, fonction de fonction et des tuples fonctionnent.

Essayez maintenant ceci: xxx

hmmm, également générique. Que diriez-vous: xxx

aha, dès que j'ai un (+) là, il devient int Pour une raison quelconque.
Continuons à jouer: xxx

hmmm, intéressant. S'avère si je fais la fonction inline , alors f # les le considère comme générique, mais cela lui donne également ce bizarre quand clause, et mon Les paramètres génériques ont ce symbole étrange ^ au lieu de la tique habituelle.
Cette syntaxe étrange est appelée "Paramètres de type résolus statiquement" (voir ici pour une explication quelque peu cohérente), et l'idée de base est que la fonction (+) nécessite que ses arguments disposent d'un membre statique (+) défini. Voyagons: xxx

Maintenant, le problème avec ceci est que le CLR ne prend pas en charge ce type de paramètres génériques (c.-à-d. "Toute sorte, tant qu'il a de tels membres "), donc f # doit faux et résoudre ces appels à la compilation. Mais à cause de cela, toute méthode qui utilise cette fonctionnalité ne peut pas être compilée à des méthodes de TRUE génériques IL, et doit donc être monomorphisée (qui est activée par en ligne ).

Mais alors, il serait très gênant d'exiger que chaque fonction utilisant des opérateurs arithmétiques soit déclarée en ligne , n'est-ce pas? Donc, F # va encore une autre étape supplémentaire et essaie de résoudre ces paramètres génériques résolus statilement basés sur la manière dont ils sont instanciés ultérieurement dans le code. C'est pourquoi votre fonction se transforme en string-> string-> chaîne dès que vous l'utilisez avec une chaîne une fois.

mais si vous marquez votre Fonction inline , f # n'aurait pas à corriger les paramètres, car il ne serait pas nécessaire de compiler la fonction jusqu'à IL, de sorte que vos paramètres restent intacts: xxx


2 commentaires

"C'est un squelette embarrassant de F # dans le placard." -- le seul?


Je suis sûr qu'il y en a plusieurs, mais je ne me souviens plus du sommet de ma tête.