Evaluer simplement une action IO
ne fait rien du tout. Vous pouvez penser à IO
comme un très gros type de somme de toutes les choses secondaires possibles Haskell peut faire faire, même si elle n'est pas réellement mise en œuvre comme ça du tout. Quelque chose comme ceci:
data IO a where
PutStrLn :: String -> IO()
ReadFile :: FilePath -> IO String
ExitWith :: ExitCode -> IO a
...
L'un des IO
constructeurs dans cette visualisation théorique serait un constructeur Sequence
, avec une signature de type comme celui-ci:
Sequence :: IO a -> (a -> IO b) -> IO b
Ce constructeur est utilisé pour mettre en œuvre >>=
pour le IO
type.
À l'intérieur de GHC est une fonction magique appelée magicallyExecuteIO
avec le type IO a -> a
, qui coordonne pour chaque action d'effectuer réellement son effet secondaire correspondant. (Incidemment, cette fonction est aussi parfois prononcée unsafePerformIO
.) GHC appelle implicitement magicallyExecuteIO
sur le résultat de la fonction main
de votre programme, ainsi que sur les expressions écrites en GHCi.
Cependant, sans utiliser magicallyExecuteIO
, l'évaluation d'un des constructeurs IO
comme PutStrLn
ne fait rien. Dans cette mise en œuvre, il serait tout simplement travailler comme tout autre constructeur de données:
ghci> Just (PutStrLn "hello!")
Just (PutStrLn "hello!") :: Maybe (IO())
(. Je l'ai enveloppé avec Just
pour empêcher GHCi d'exécuter l'action IO
)
Bien sûr, IO
réelle de GHC Type n'est pas implémenté de cette façon, mais c'est juste un détail d'implémentation. L'évaluation d'une valeur IO a
ne provoque pas d'effet secondaire plus qu'une évaluation d'une valeur Maybe a
. Seulement magicallyExecuteIO
peut le faire.
Veuillez consulter http://stackoverflow.com/help/mcve. La plupart de vos importations ne sont pas pertinentes, ici. 'sillyIO' n'est défini nulle part. 'sillyDebug = (trace (show x) False) \' seq \ '(x + y)' ne compile même pas. Et décrivez le problème auquel vous êtes confronté. Qu'est-ce que vous attendiez? Qu'est ce que tu obtiens? – Jubobs
Désolé, c'est de ma faute: 3 –
Ce problème concerne la différence entre * évaluer * une expression et * exécuter * une action monadique, mais je pense qu'il vaut également la peine de faire une note sur 'seq'. '' '' 'seq' b'' ne force pas forcément l'évaluation de' a'. Il génère une dépendance entre thunks, donc * si * 'b' est évalué, alors' a' l'est aussi. '' print (snd (x 'seq'y, z))' 'n'évalue jamais' x' car il n'évalue jamais 'y'. –