J'ai 3 questions, en fait :
Q.1) A propos des monades, j'aimerais savoir, est-ce que c'est seulement la monade IO qui est stricte ou bien est-ce que toutes les monades le sont ?
Q.2) Et surtout, est-ce que les monades assurent que dans l'expression suivante :
'f x' va être évalué AVANT g qui sera évalué AVANT h ? Je pense que oui, vu que je ne vois pas comment on peut obtenir le résultat de h sans avoir obtenu au préalable celui de g.
Exemple avec Parsec (chap. 16 de Real World Haskell, ou on définit un parser HTTP) :
p_pair = liftM2 (,) (many1 p_char) (optionMaybe $ char '=' >> many p_char)
Pour que le parsage marche comme on l'entend, il est nécessaire que le code en vert soit évalué avant ce qui est en rouge (et on est toujours dans du code pur).
Q.3) Toujours concernant cet exemple de RWH, ils définissent dans le même chapitre GenParser comme un Applicative:
1 2 3
| instance Applicative (GenParser s a) where
pure = return
(<*>) = ap |
ce qui fait que le code précédent peut s'écrire de la sorte
a_pair = liftA2 (,) (many1 a_char) (optionMaybe $ char '=' *> many a_char)
Encore une fois, le fait que le premier arguement de 'liftA2 (,)' soit évalué AVANT le deuxième est-il assuré par les Applicatives ?
Car cette fois-ci, par contre, dans l'expression :
a = pure f <*> b <*> c <*> d
b, c et d sont en théorie indépendants (c'est là la différence entre <*> et >>=) donc en théorie rien n'oblige Haskell à évaluer b avant c et c avant d.
Du coup, je me demande, est-ce que le parser ne se comporte-t-il correctement que parce que son instance d'Applicative est construite avec des opérations de Monad ?
Si c'est le cas, alors les Applicatives ne conviennent pas au parsage, et du coup c'est assez idiot de la part des auteurs de RWH de nous avoir sorti cet exemple.
Partager