Ce code (extrait de Décentrez-vous un haskell ): Apparemment Desgesnes à p> putStrLn "What is your name?" >>=
(\_ ->
getLine >>=
(\name ->
putStrLn ("Nice to meet you, " ++ name ++ "!")))
5 Réponses :
Lire le " S'attaquer à l'équipe gênante "Papier par Simon Peyton Jones.
Pour des questions connexes, voir P>
Prenez une telle explication, y compris la mine avec un grain de sel - aucune ondulation de la main ne peut remplacer un papier rigoureux à examiné par des pairs, et les explications sont nécessairement excessivement simplifiantes. P>
La perspective rugueuse est que >> = code> peut être considéré comme un constructeur de liste: p>
data IO = [Primitive]
Il est intéressant de noter que tout le monde explique toujours >> = sur les valeurs IO par analogie. N'a-t-il pas une définition quelque part dans le prélude? Pourquoi personne ne le cite-t-il jamais? Est lié sur io où la magie se produit? Je lis le papier d'équipe maladroite en ce moment et même SPJ vous échappe de définir réellement la liaison
Le type io code> est abstrait, il n'y a donc personne de définition de
>> = code> dans la norme HASKELLL. Selon la manière dont vous implémentez
io code>, vous aurez des implémentations différentes de
>> = code>. Si vous approchez dans GHC, vous constaterez que
io code> est une monade d'état et
>> = code> est simplement lié pour une monade d'état. (Il y a plus de magie à l'intérieur du compilateur pour rendre cela efficace.)
@Thelronknuckle Ce n'est pas une analogie sur les "valeurs". C'est une analogie sur une autre implémentation d'IO pure à l'aide de l'ancien Main :: [Demande] -> [réponse] code> idée. La partie la plus intéressante n'est également pas liée, mais du
runio code> pour io monade. Comme Io Monad est abstrait, nous devons soit fournir une explication abstraite en tant que SPJ, ou utilisez une stratégie de mise en œuvre comme moi.
Je pense que cela est plus compréhensible si vous pensez à nouveau aux actions en tant que fonctions. Votre exemple de liaison ( sauf que la fonction est une transaction. Notre appel Ceci est différent des fonctions ordinaires, car alors Haskell ne se soucie vraiment pas si do {foo <- getline; poststrln foo;} code>) est de manière intuitive similaire à la fonction suivante:
FUNC (ARG) CODE> est évalué, le cas échéant si
(arg) code> est terminé avec succès. Sinon, nous
(arg) code> calcule complètement ou à Tout, jusqu'à ce que le point ait besoin d'un peu de
Func (arg) code> pour poursuivre le programme. p> p>
regarder donc lorsque vous évaluez un programme (de type SO P> io code> dans une réelle implémentation de haskell confondra probablement plus qu'elles éclaire. Mais pensez que
io code> comme étant défini comme celui-ci (cela suppose que vous connaissez des gains):
io () code>) Tout ce qu'il fait est de créer une structure de données de type
io () code> qui décrit comment l'interaction avec le monde se produira une fois que vous l'exécutez. Vous pouvez alors imaginer que le moteur d'exécution étant écrit, par exemple, C, et il y a là où tous les effets se produisent. P>
main = Bind (PutStr "Hey, ") (\ _ -> Bind (PutStr "I'm ") (\ _ -> PutStr "Andy!"))
+1 pour l'approche de GADT et le «regard sur l'IO dans une réelle implémentation de Haskell confondra probablement plus qu'elles éclaire».
Je pense avoir juste besoin de voir la définition de la liaison pour io, puis sera tout clair. p>
Oui, vous devriez le faire. C'est en fait assez facile, et si je me remette correctement, ça va comme p>
xxx pré> le "truc" est que chaque valeur IO est en fait fondamentalement une fonction, mais pour l'évaluer, vous auriez besoin de Un jeton de type
realworld code>. Il n'y a qu'une seule instance qui peut fournir une telle valeur - le système d'exécution fonctionnant principal (et, bien sûr, la fonction qui ne doit pas être nommée). P> blockquote>
Je pense que je dois juste voir la définition de
bind code>
IO code> et alors il sera clair. P>
IO (\ s0 -> let !(# s1, _ #) = unIO (putStrLn "What is your name?") s0 in let !(# s2, name #) = unIO getLine s1 in let !(# s3, a3 #) = unIO (putStrLn ("Nice to meet you, " ++ name ++ "!")) s2 in (# s3, a3 #))
"Les Lambdas ignorent leurs arguments, lors de l'évaluation paresseuse, ce type de chose n'est censé être reconnu et court-circuité?" Tu paries! Le deuxième argument à
(>> =) code> est une fonction particulièrement paresseuse ici, mais le
(>> =) code> fonction elle-même i> n'est pas paresseux.