663 votes

Comment une fonction temporelle peut exister dans la programmation fonctionnelle ?

Je dois vous avouer que je ne sais pas beaucoup sur la programmation fonctionnelle. J'ai lu ici et là, et donc est venu de savoir que dans la programmation fonctionnelle, une fonction retourne le même résultat, pour la même entrée, peu importe combien de fois que la fonction est appelée. C'est exactement comme une fonction mathématique qui évalue à même de sortie pour une même valeur de paramètre d'entrée qui comporte l'expression de fonction.

Par exemple, considérez ceci:

f(x,y) = x*x + y; //it is a mathematical function

Peu importe combien de fois vous utilisez f(10,4), sa valeur sera toujours 104. Que, peu importe ce que vous avez écrit f(10,4), vous pouvez le remplacer par 104, sans altérer la valeur de l'expression complète. Cette propriété est appelée la transparence référentielle d'une expression.

Comme dit Wikipedia (lien),

À l'inverse, dans le code fonctionnel, la valeur de sortie d'une fonction dépend uniquement sur les arguments d'entrée de la fonction, de sorte que l'appel d'une fonction f deux fois avec la même valeur d'un argument x produira le même résultat f(x) deux fois.

Donc ma question est: est-ce une fonction de temps (qui renvoie le courant du temps) existent dans la programmation fonctionnelle?

  • Si oui, alors comment peut-il exister? N'est-il pas contraire au principe de la programmation fonctionnelle? Il est particulièrement viole la transparence référentielle qui est celui de la propriété de la programmation fonctionnelle (si j'ai correctement le comprendre).

  • Ou si non, alors comment peut-on savoir à l'heure actuelle dans la programmation fonctionnelle?

364voto

Carsten König Points 14720

Oui et non.

Différents FP langues résoudre différemment.

En Haskell (un très pure) de tout ce qui doit arriver à quelque chose qui s'appelle le IO Monade - voir ici. Vous pouvez penser que l'obtention d'une autre entrée (et de sortie) dans votre fonction (le monde-état) ou plus facile comme un lieu où "impureness" comme obtenir le changement de temps se passe.

D'autres langues comme le F# tout simplement avoir impureness construit dans et vous pouvez donc avoir une fonction qui retourne une valeur différente pour la même entrée - comme normale des langages impératifs.

Comme Jeffrey Burka a mentionné dans son commentaire: Voici la belle intro à la IO Monade directement à partir de la HaskellWiki.

187voto

dainichi Points 755

Une autre façon d'expliquer ce qu'elle est: pas de fonction peut obtenir l'heure actuelle (depuis il ne cesse de changer), mais une action peut obtenir l'heure actuelle. Disons qu' getClockTime est une constante (ou un nullary fonction, si vous le souhaitez), qui représente l' action d'obtenir l'heure actuelle. Cette action est la même à chaque fois, peu importe quand il est utilisé de sorte qu'il est un réel constant.

De même, disons - print est une fonction qui prend un certain temps de la représentation et l'imprime à la console. Depuis les appels de fonction ne peut pas avoir des effets secondaires en langage purement fonctionnel, nous avons plutôt imaginer que c'est une fonction qui prend un horodatage et renvoie à l' action de l'impression à la console. Encore une fois, c'est une fonction réelle, parce que si vous donnez la même heure, il sera de retour la même action de l'impression à chaque fois.

Maintenant, comment pouvez-vous imprimer à l'heure actuelle à la console? Eh bien, vous devez combiner les deux actions. Alors, comment pouvons-nous le faire? Il ne suffit pas de transmettre getClockTime de print, depuis l'impression attend un timestamp, pas une action. Mais on peut imaginer qu'il est un opérateur, >>=, qui combine deux actions, l'une qui reçoit un timestamp, et celui qui prend un argument et l'imprime. L'application de ce que les actions mentionné précédemment, le résultat est... tadaaa... une nouvelle action, qui obtient l'heure actuelle et l'imprime. Et c'est incidemment exactement comment il est fait en Haskell.

Prelude> System.Time.getClockTime >>= print
Fri Sep  2 01:13:23 東京 (標準時) 2011

Donc, sur le plan conceptuel, vous pouvez le voir de cette façon: Un pur programme fonctionnel n'effectue pas de IO, il définit une action, le système d'exécution exécute alors. L' action est la même à chaque fois, mais le résultat de l'exécution d'elle dépend des circonstances du moment où elle est exécutée.

Je ne sais pas si c'était plus clair que les autres explications, mais parfois il m'aide à penser à elle de cette façon.

148voto

FUZxxl Points 21462

En Haskell, on utilise une construction appelée monade pour gérer les effets secondaires. Une monade, fondamentalement signifie que vous encapsuler des valeurs dans un récipient et ont certaines fonctions de la chaîne de fonctions à partir de valeurs de valeurs à l'intérieur d'un conteneur. Si notre conteneur est du type:

data IO a = IO (RealWorld -> (a,RealWorld))

nous pouvons mettre en œuvre IO actions. Ce type de moyens: Une action de type IO est une fonction, qui prend un jeton de type RealWorld et retourne un nouveau jeton, avec un résultat.

L'idée derrière cela est que chaque IO action de la mutation de l'extérieur de l'état, représenté par la magie de jeton RealWorld. À l'aide de monades, on peut chaîner plusieurs fonctions qui muter le monde réel de l'ensemble. La fonction la plus importante d'une monade est - >>=, prononcé lier:

(>>=) :: IO a -> (a -> IO b) -> IO b

>>= a qu'une et une fonction qui prend la suite de cette action, et crée une nouvelle action de ce. Le type de retour est la nouvelle action. Par exemple, imaginons une fonction now :: IO String, qui retourne une Chaîne de caractères représentant l'heure actuelle. Nous pouvons de la chaîne avec la fonction putStrLn à imprimer:

now >>= putStrLn

Ou écrit en do-de la Notation, qui est plus familier à un impératif programmeur:

do currTime <- now
   putStrLn currTime

Tout cela est pure, comme nous la carte de la mutation et de l'information sur le monde en dehors de l' RealWorld jeton. Donc, à chaque fois, vous exécutez cette action, vous obtenez bien sûr un autre outut, mais l'entrée n'est pas la même - RealWorld-jeton.

74voto

sepp2k Points 157757

La plupart des langages de programmation fonctionnelle ne sont pas purs, c'est à dire qu'ils permettent de fonctions dépend pas seulement de leurs valeurs. Dans ces langues, il est parfaitement possible d'avoir une fonction retournant l'heure actuelle. Parmi les langues que vous marqués cette question avec cela s'applique à la scala et f# (ainsi que la plupart des autres variantes de ML).

Dans des langages comme Haskell et Propre, ce qui est pur, la situation est différente. En Haskell l'heure actuelle ne serait pas disponible au travers d'une fonction, mais un soi-disant IO action, qui est Haskell manière d'encapsuler des effets secondaires.

Dans les Nettoyer serait une fonction, mais la fonction serait de prendre un monde valeur de ses arguments et retourne une nouvelle valeur mondiale (en plus de l'heure actuelle) que son résultat. Le type de système serait de s'assurer que chaque valeur peut être utilisée qu'une seule fois (et à chaque fonction qui consomme un monde de valeur produit un nouveau). De cette façon, le temps de fonction doit être appelée avec un argument différent à chaque fois, et, donc, être autorisé à revenir une autre fois à chaque fois.

52voto

Vlad Patryshev Points 717

« L’heure actuelle » n’est pas une fonction. Il s’agit d’un paramètre. Si votre code dépend de l’heure actuelle, cela signifie que votre code est paramétré par le temps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X