Question

Cela fait un moment que j'essaie de parler de fa #, mais je continue de m'inquiéter. Pourquoi?

Parce que quelle que soit la ressource "débutant" que j'essaie de consulter, je vois des exemples très simples qui commencent à utiliser l'opérateur - > .

Cependant, je n’ai encore trouvé nulle part ailleurs une explication claire et simple de la signification de cet opérateur. C'est comme si cela devait être tellement évident qu'il n'a pas besoin d'explication même pour compléter les débutants.

Je dois donc être très dense ou peut-être que c'est près de 3 décennies d'expérience antérieure qui me retient.

Quelqu'un peut-il s'il vous plaît expliquer ou indiquer une ressource vraiment accessible qui l'explique?

Était-ce utile?

La solution

'- >' n'est pas un opérateur. Il apparaît dans la syntaxe F # à plusieurs endroits et sa signification dépend de la manière dont il est utilisé dans le cadre d'une construction plus grande.

À l'intérieur d'un type, '- >' décrit les types de fonctions décrites ci-dessus. Par exemple

let f : int -> int = ...

dit que 'f' est une fonction qui prend un int et retourne un int.

Dans un lambda ("chose commençant par" mot clé "amusant"), '- >' est une syntaxe qui sépare les arguments du corps. Par exemple

fun x y -> x + y + 1

est une expression qui définit une fonction à deux arguments avec l'implémentation donnée.

À l'intérieur d'un "match". construire, '- >' Cette syntaxe sépare les modèles du code à exécuter si le modèle correspond. Par exemple, dans

match someList with
| [] -> 0
| h::t -> 1

le contenu à gauche de chaque '- >' sont des motifs, et ce qui se passe à droite correspond à ce qui se passe si le motif de gauche correspondait.

La difficulté à comprendre peut s’expliquer par l’hypothèse erronée selon laquelle '- >' est " un opérateur " avec un seul sens. Une analogie pourrait être "." en C #, si vous n'avez jamais vu de code auparavant et essayez d'analyser le ". " opérateur basé sur la recherche " méthode obj " et "3,14" et "System.Collections", vous pourriez être très confus, car le symbole a différentes significations dans différents contextes. Une fois que vous en connaissez suffisamment le langage pour reconnaître ces contextes, les choses deviennent claires.

Autres conseils

Cela signifie essentiellement "cartes en". Lisez-le ainsi ou alors que " est transformé en " ou quelque chose comme ça.

Donc, à partir du F # dans 20 minutes ,

> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]
  

Le code (fun i - > i% 2 = 0) définit   une fonction anonyme, appelée lambda   expression, qui a un paramètre x et   la fonction renvoie le résultat de "x   % 2 = 0 ", que x soit ou non   même.

Première question - connaissez-vous les expressions lambda en C #? Si tel est le cas, > dans F # est le même que le = > en C # (je pense que vous lisez "va à").

Le - > opérateur peut également être trouvé dans le contexte de la correspondance de modèle

match x with
| 1 -> dosomething
| _ -> dosomethingelse

Je ne suis pas sûr que ce soit aussi une expression lambda ou autre chose, mais je suppose que le "va à" est toujours valable.

Vous faites peut-être réellement référence aux réponses "cryptiques" de l'analyseur F #:

> let add a b = a + b
val add: int -> int -> int

Cela signifie (comme l'expliquent la plupart des exemples) que add est un 'val' qui prend deux ints et renvoie un int. Pour moi, c'était totalement opaque pour commencer. Je veux dire, comment puis-je savoir que add n'est pas une valeur qui prend un int et renvoie deux ints?

Eh bien, l’essentiel est que dans un sens, c’est le cas. Si je ne rajoute qu’un seul int, je récupère un (int - > int):

> let inc = add 1
val inc: int -> int

Ceci (le currying) est l’une des choses qui rendent F # si sexy, pour moi.

Pour des informations utiles sur le F #, j’ai trouvé que les blogs sont beaucoup plus utiles que les documents officiels: voici quelques noms à consulter

(a -> b) signifie "fonction de a à b". Dans l'annotation de type, il s'agit d'un type de fonction. Par exemple, f: (int - > String) signifie que f fait référence à une fonction qui prend un entier et renvoie une chaîne. Il est également utilisé pour contrôler de telles valeurs, comme dans

val f : (int -> int) = fun n -> n * 2

qui crée une valeur qui est une fonction d'un nombre n à ce même nombre multiplié par deux.

Il y a déjà beaucoup de bonnes réponses ici, je veux juste ajouter à la conversation une autre façon de penser.

'- > 'signifie fonction.

'a - > 'b est une fonction qui prend un' a et retourne un 'b

('a *' b) - > ('c *' d) est une fonction qui prend un tuple de type ('a,' b) et retourne un tuple de ('c,' d). Tels que int / string retourne float / char.

Ce qui est intéressant, c’est dans le cas en cascade 'a - > 'b - > 'c. C'est une fonction qui prend un 'a et retourne une fonction (' b - > 'c), ou une fonction qui prend un' b - > 'c.

Donc si vous écrivez:  laisser f x y z = ()

Le type sera f: 'a - > 'b - > 'c - > unité, donc si vous appliquiez uniquement le premier paramètre, le résultat serait une fonction curry 'b - > 'c - > 'unité.

De Microsoft :

  

Les types de fonction sont les types donnés à   valeurs de fonction de première classe et sont   écrit int - > int. Ils sont similaires   aux types de délégués .NET, sauf qu'ils   ne sont pas des noms donnés. Toutes les fonctions F #   les identifiants peuvent être utilisés en première classe   valeurs de fonction et anonymes   les valeurs de fonction peuvent être créées en utilisant   la forme d'expression (amusante ... - > ...).

Beaucoup de bonnes réponses à ces questions, merci aux gens. Je voudrais mettre ici une réponse modifiable qui rassemble les choses.

Pour ceux qui sont familiarisés avec la compréhension de C # - > étant le même que = > L'expression de lamba est un bon premier pas. Cet usage est: -

fun x y -> x + y + 1

Peut être compris comme l'équivalent de: -

(x, y) => x + y + 1;

Cependant, il est clair que - > a une signification plus fondamentale qui découle du concept selon lequel une fonction qui prend deux paramètres tels que ceux mentionnés ci-dessus peut être réduite (est-ce le bon terme?) à une série de fonctions ne prenant qu'un paramètre.

Par conséquent, lorsque ce qui précède est décrit comme suit: -

Int -> Int -> Int

Cela a vraiment aidé de savoir que - > est juste associatif d'où ce qui précède peut être considéré: -

Int -> (Int -> Int)

Aha! Nous avons une fonction qui prend Int et renvoie (Int - & Int) (une fonction curry?).

L'explication selon laquelle - > peut également apparaître dans le cadre de la définition du type également aidé. (Int - > Int) est le type d’une fonction quelconque qui prend un Int et retourne un Int.

Le - > apparaît dans une autre syntaxe telle que matching mais n'y a-t-il pas la même signification? Est-ce exact? Je ne suis pas sûr que ça l'est. Je suppose que cela a le même sens, mais je n'ai pas encore le vocabulaire pour l'exprimer.

Notez que le but de cette réponse n’est pas d’engendrer d’autres réponses mais d’être édité en collaboration par vos collaborateurs pour créer une réponse plus définitive. Pratiquement, il serait bon que toutes les incertitudes et fluf (comme ce paragraphe) soient supprimés et de meilleurs exemples ajoutés. Essayons de garder cette réponse aussi accessible que possible aux non-initiés.

Dans le contexte de la définition d'une fonction, cela ressemble à = & de l'expression lambda en C # 3.0.

F#: let f = fun x -> x*x
C#: Func<int, int> f = x => x * x;

Le - > dans F # est également utilisé dans la correspondance de modèles, où il signifie: si l'expression correspond à la partie comprise entre | et - > , ce qui vient après - > doit être rendu comme résultat:

let isOne x = match x with
 | 1 -> true
 | _ -> false

Ce qu'il y a de bien avec des langages tels que Haskell (il est très similaire en fa #, mais je ne connais pas la syntaxe exacte - cela devrait vous aider à comprendre - > ;, cependant) est que vous ne pouvez appliquer que des parties de l'argument , pour créer des fonctions curried :

adder n x y = n + x + y

En d'autres termes: "donnez-moi trois choses et je les ajouterai ensemble". Lorsque vous lancez des nombres, le compilateur déduit les types de n x et y. Dis que tu écris

adder 1 2 3

Le type de 1, 2 et 3 est Int. Par conséquent:

adder :: Int -> Int -> Int -> Int

C’est-à-dire donnez-moi trois nombres entiers et je deviendrai éventuellement un nombre entier, ou la même chose que si vous disiez:

five :: Int
five = 5

Mais voici la belle partie! Essayez ceci:

add5 = adder 5

Comme vous vous en souvenez, l'additionneur prend un int, un int, un int et vous rend un int. Cependant, ce n'est pas toute la vérité, comme vous le verrez bientôt. En fait, add5 aura ce type:

add5 :: Int -> Int -> Int

Ce sera comme si vous aviez "pelé" des entiers (le plus à gauche), et collé directement à la fonction. En regardant de plus près la signature de la fonction, nous remarquons que le - > sont à droite associative, c'est-à-dire:

addder :: Int -> (Int -> (Int -> Int))

Cela devrait être très clair: lorsque vous donnerez le premier entier à l'additionneur, il sera évalué par tout ce qui se trouve à droite de la première flèche, ou:

add5andtwomore :: Int -> (Int -> Int)
add5andtwomore = adder 5

Vous pouvez maintenant utiliser add5andtwomore au lieu de "additionneur 5". De cette façon, vous pouvez appliquer un autre entier pour obtenir (par exemple) "add5and7andonemore":

add5and7andonemore :: Int -> Int
add5and7andonemore = adder 5 7

Comme vous le voyez, add5and7andonemore veut exactement un autre argument, et lorsque vous lui en donnez un, il deviendra soudainement un entier!

  > add5and7andonemore 9
 => ((add5andtwomore) 7) 9
 => ((adder 5) 7) 9)
<=> adder 5 7 9

En substituant les paramètres à l'additionneur (n x y) pour (5 7 9), on obtient:

  > adder 5 7 9 = 5 + 7 + 9
 => 5 + 7 + 9
 => 21

En fait, , plus n’est qu’une fonction qui prend un int et vous redonne un autre int. La description ci-dessus ressemble donc beaucoup plus à:

  > 5 + 7 + 9
 => (+ 5 (+ 7 9))
 => (+ 5 16)
 => 21

Voilà!

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