Récemment, j'ai commencé à apprendre Haskell parce que je voulais élargir mes connaissances sur la programmation fonctionnelle et je dois dire que je l'aime vraiment jusqu'à présent. La ressource que j'utilise actuellement est le cours «Haskell Fundamentals Part 1» sur Pluralsight. Malheureusement, j'ai du mal à comprendre une citation particulière du conférencier au sujet du code suivant et j'espérais que vous pourriez éclairer le sujet.
Code d'accompagnement
helloWorld :: IO ()
helloWorld = putStrLn "Hello World"
main :: IO ()
main = do
helloWorld
helloWorld
helloWorld
La citation
Si vous avez la même action IO plusieurs fois dans un do-block, elle sera exécutée plusieurs fois. Ce programme imprime donc la chaîne «Hello World» trois fois. Cet exemple permet d'illustrer que ce putStrLn
n'est pas une fonction avec des effets secondaires. Nous appelons la putStrLn
fonction une fois pour définir la helloWorld
variable. Si cela putStrLn
avait pour effet secondaire d'imprimer la chaîne, elle ne s'imprimerait qu'une seule fois et la helloWorld
variable répétée dans le do-block principal n'aurait aucun effet.
Dans la plupart des autres langages de programmation, un programme comme celui-ci n'imprimait 'Hello World' qu'une seule fois, car l'impression se produisait lorsque la putStrLn
fonction était appelée. Cette distinction subtile ferait souvent trébucher les débutants, alors pensez-y un peu et assurez-vous de comprendre pourquoi ce programme imprime `` Hello World '' trois fois et pourquoi il ne l'imprimerait qu'une seule fois si la putStrLn
fonction faisait l'impression comme effet secondaire.
Ce que je ne comprends pas
Pour moi, il semble presque naturel que la chaîne «Hello World» soit imprimée trois fois. Je perçois la helloWorld
variable (ou la fonction?) Comme une sorte de rappel qui est invoqué plus tard. Ce que je ne comprends pas, c'est que si cela putStrLn
avait un effet secondaire, cela entraînerait l'impression de la chaîne une seule fois. Ou pourquoi il ne serait imprimé qu'une seule fois dans d'autres langages de programmation.
Disons que dans le code C #, je suppose que cela ressemblerait à ceci:
C # (violon)
using System;
public class Program
{
public static void HelloWorld()
{
Console.WriteLine("Hello World");
}
public static void Main()
{
HelloWorld();
HelloWorld();
HelloWorld();
}
}
Je suis sûr que j'oublie quelque chose d'assez simple ou que je interprète mal sa terminologie. Toute aide serait grandement appréciée.
ÉDITER:
Merci à tous pour vos réponses! Vos réponses m'ont aidé à mieux comprendre ces concepts. Je ne pense pas qu'il ait complètement cliqué pour le moment, mais je reviendrai sur le sujet à l'avenir, merci!
putStrLn
n'a pas d'effet secondaire; il renvoie simplement une action IO, la même action IO pour l'argument, "Hello World"
quel que soit le nombre de fois que vous appelez putStrLn
.
helloworld
serait pas une action qui s'imprime Hello world
; ce serait la valeur renvoyée par putStrLn
après son impression Hello World
(à savoir, ()
).
helloWorld = Console.WriteLine("Hello World");
. Vous venez de contenir la Console.WriteLine("Hello World");
dans la HelloWorld
fonction à exécuter chaque fois que vous HelloWorld
invoquez. Pensez maintenant à ce qui helloWorld = putStrLn "Hello World"
fait helloWorld
. Il est affecté à une monade IO qui contient ()
. Une fois que vous le lierez, il >>=
effectuera seulement son activité (impression de quelque chose) et vous donnera ()
sur le côté droit de l'opérateur de liaison.
helloWorld
être constant comme un champ ou une variable en C #. Aucun paramètre n'est appliquéhelloWorld
.