Question

en train de lire une série de F # sur blogposts, destiné au programmeur C #. En ce moment, la lecture que j'ai terminé la partie 3 ( http://www.jelovic.com/weblog/ ? p = 220 ) et suis resté perplexe.

La différence entre

  

let readLine = Console.ReadLine ()

et

  

let readLine () = Console.ReadLine ()

est assez clair, mais pourquoi est-il nécessaire de préciser les deux accolades - () - dans la ligne suivante:

  

let impression (texte: string) () = text Console.WriteLine

ne doit pas être le compilateur en mesure de déterminer vous déclarer une impression de délégué en omettant les accolades, il se présente comme suit:

  

let impression (texte: string) = text Console.WriteLine

En outre, la ligne suivante m'a fait peu de sens

  

Habituellement, lorsque vous avez une fonction qui prend des paramètres d'un type différent le compilateur peut faire la différence entre un appel de fonction et une référence de délégué, mais pour l'unité que vous devez forcer.

Est-ce que cela signifie que lorsque les paramètres sont différents, il est sûr que le compilateur suppose qu'il est un appel de fonction?

merci à vous tous pour les réponses, il est clair pour moi maintenant. Quant à la citation, nous allons laisser reposer.

Était-ce utile?

La solution

Introduction. Je pense qu'il est utile d'examiner d'abord la différence de l'exemple simple car il aide à comprendre ce que la valeur « unité » est. La première déclaration crée une valeur de chaîne (et appelle immédiatement ReadLine pour obtenir l'entrée de l'utilisateur):

> let readLine = Console.ReadLine ();;
val readLine : string

La seconde déclaration crée une fonction qui prend la valeur unitaire comme argument. La fonction n'a pas besoin de prendre une entrée, mais nous voulons le définir en fonction, afin qu'il puisse être exécuté à plusieurs reprises (nous en avons besoin, parce que la fonction a effet secondaire - il lit entrée de l'utilisateur).

Le paramètre « unité » est juste une façon de créer une fonction qui prend quelque chose comme argument. « Unité » ne dispose que d'une seule valeur écrite comme (), il ne représente aucune information - juste le fait qu'il ya un paramètre:

> let readLine () = Console.ReadLine ();;
val readLine : unit -> string

Votre question. Pour regarder votre exemple avec des accolades supplémentaires. Cela crée une fonction qui prend une chaîne de caractères en tant que premier paramètre et prend la valeur « unitaire » supplémentaire en tant que second paramètre. Vous pouvez voir que de la signature de type:

> let print (text : string) () = Console.WriteLine text 
val print : string -> unit -> unit

Ceci est valable F # déclaration, mais il est pas très utile. Cela signifie que la fonction sera appelée que lorsque vous donnez une chaîne à imprimer et aussi la valeur « unité » supplémentaire. Vous pouvez l'appeler comme ceci:

print "Hello" ()

Même sans le paramètre « unité » supplémentaire, ce serait une fonction (par opposition à une valeur), afin d'ajouter le paramètre supplémentaire ne aide (vous créez toujours une fonction qui peut être appelée à imprimer des chaînes différentes ).

Il y a encore des cas où cette déclaration peut être intéressante. Par exemple, vous pouvez appeler la fonction juste avec la chaîne en tant que paramètre. Dans ce cas, vous aurez une fonction à la suite. La fonction de retour prendra unité et imprimera la chaîne:

let f = print "Hello" // doesn't print anything
f ()                  // prints "Hello"
f ()                  // prints "Hello" again!

Ainsi, le compilateur vous permet d'utiliser des valeurs « unitaires » comme toutes les autres valeurs dans la langue. Cela inclut les utilisations qui peuvent paraître un peu familier (et pas très utile) au début, mais peut faire un bon sens dans un scénario.

Autres conseils

let print (text : string) = Console.WriteLine text

crée une méthode d'impression comme:

print "hi" // prints "hi" in the console

où:

let print (text : string) () = Console.WriteLine text

produit une méthode pour imprimer une chaîne spécifique comme:

let printHi = print "hi" // Does NOT print a string to the console

printHi () // But now this does print "hi" :)
printHi () // And this...

Donc, essentiellement, il est une usine « impression chaîne spécifique à la fonction X de la console » dont le résultat (ex printHi) peut être réutilisé plusieurs fois.

Utilisation curryfication,

let makePrinter (text : string) () = Console.WriteLine text

nous allons vous créer une fonction qui imprime toujours une certaine chaîne, par exemple

let helloPrinter = makePrinter "hello"

donne "bonjour" en appelant simplement

helloPrinter ()

Par contre,

let print (text : string) = Console.WriteLine text

Sorties immediat "texte" si elle est appelée

print "hello"

et les retours (), et non pas une fonction de type unit -> unit comme dans le premier, le curry cas.

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