
Le 26 mars 2014 18:04, Sylvain Henry
Bonjour,
J'avais fait un exposé pour expliquer ça entre autres, je ne sais pas si c'est tellement compréhensible sans les explications données à l'oral mais les slides sont là : http://www.sylvain-henry.info/home/data/uploads/talks/shenry-2013-02-05-haskell-intro.pdf(à partir du 20e slide).
* Contexte
Dans un langage fonctionnel, on n'utilise pas de variable globale donc pour qu'il y ait un contexte il faut le passer explicitement en entrée des fonctions et le renvoyer en sortie (en plus d'autres valeurs potentiellement) : f :: ... -> Context -> (Context, ...)
pour ne pas écrire à chaque fois les types "Context", on peut faire : type M a = Context -> (Context, a) et réécrire : f :: ... -> M a
ok, déjà ça c'est plus clair.
Il ne reste plus qu'à définir la composition pour les fonctions de ce type de sorte que le contexte soit passé de la sortie de la première fonction à l'entrée de l'autre : (>>=) :: M a -> (a -> M b) -> M b (>>=) f g = \ctx -> let (ctx2, a) = f ctx in g a ctx2
C'est là que je décroche, après un >>= on a bien une fonction qui attends un paramètre ? si oui, qui lui donne ?
Pour créer une fonction de type "M a" à partir d'un "a", on définit la fonction : return :: a -> M a return x = \ctx -> (ctx,x)
idem
* IO
Dans le cas des IO, le "contexte" est le "monde" (extérieur au programme). La fonction main a le type suivant : main :: IO () soit main :: World -> (World, () )
Donc on peut composer des fonctions qui ont des effets de bord avec (>>=) de sorte que ce soit correct d'un point de vue types sans jamais dire exactement ce que représente le type World. Les opérations s'exécutent en séquence puisque chaque opération "attend de récupérer le monde renvoyé par l'opération qui la précède" (du moins c'est l'idée). Il n'y a aucun moyen pour le programme de créer un objet de type World donc toutes les opérations s'enchainent forcément à partir de celui passé à "main".
ça ok, mais comment les mondes se "passent" entre les différents appel (bien que d'après ce que j'ai pu lire, l'IO monade est un cas particulier).
* Monades
Les monades sont juste une généralisation du mécanisme décrit ci-dessus (en gros), c'est pourquoi ils sont adaptés. La typeclass Monad implique la typeclass Applicative (l'inverse n'est pas vrai) et on aurait pu utiliser Applicative à la place de Monad dans le cas des IOs. Ça a même été suggéré sur la mailing-list haskell-cafe il n'y a pas si longtemps si je me souviens bien.
Merci, du coup les Applicative permettent aussi des effets de bords et d'enchaînements ?