[Haskell-fr] Éclaircissements sur les monades

Valentin Robert valentin.robert.42 at gmail.com
Thu Mar 27 00:37:03 UTC 2014


Non je ne dirais pas ça.

L'idée générale est "comment peut-on appliquer fonctions en tenant compte
d'un certain contexte ?".

Une solution (fournie par Functor) est d'appliquer une fonction pure de
tout contexte (a -> b) directement sur un contexte en entrée (c a) :
c a -> (a -> b) -> c b
Dans ce cas, la structure du contexte de sortie est uniquement dépendante
de la structure du contexte de l'entrée, jamais de la fonction.

Une solution (fournie par Applicative) est d'appliquer une fonction pure
placée dans un contexte (c (a -> b)) sur l'entrée :
c a -> c (a -> b) -> c b
Dans ce cas, la structure du contexte de sortie est déterminée par le
contexte de l'entrée et le contexte de la fonction, mais toujours pas par
la fonction.

Une solution (fournie par Monad) est d'appliquer une fonciton (a -> c b)
qui produit, pour la valeur placée dans le contexte de l'entrée (le a), une
autre valeur dans un autre contexte (le (c b)) :
c a -> (a -> c b) -> c b
Dans ce cas, la structure du contexte de sortie peut être influencé par la
fonction, qui peut dépendre de la valeur dans le contexte d'entrée.



Je n'utiliserai pas le vocabulaire read/write/drop/create car je ne pense
pas que ça aidera à éclaircir les idées. Tout comme je n'utiliserai pas
d'analogie, car elles marchent souvent bien pour un exemple et très mal
pour un autre. Parler de contexte est déjà à la limite du douteux pour
certaines monades...

Si cela n'est pas très clair, ne te tracasse pas trop, et essaie de lire ou
écrire quelques programmes applicatifs et monadiques pour certaines
monades, puis de lire ou écrire quelques programmes pour des monades
génériques, et tu finiras par discerner les motifs sous-jacents.

- Valentin


2014-03-26 15:12 GMT-07:00 Gautier DI FOLCO <gautier.difolco at gmail.com>:

> Le 26 mars 2014 21:19, Valentin Robert <valentin.robert.42 at gmail.com> a
> écrit :
>
> Ci-dessous une intuition guidée par les types pour identifier une
>> différence entre les foncteurs applicatifs et les monades qui a été
>> mentionée auparavant par Alp.
>>
>> La composition de foncteurs applicatif a pour type:
>> c a -> c (a -> b)  -> c b
>> La composition de monades a pour type:
>> c a -> (a -> c b) -> c b
>>
>> (J'ai renommé les variables f et m en c, et réordonné les paramètres pour
>> simplifier mon explication)
>>
>> Dans les deux cas, on souhaite applique uniformément une sorte de
>> fonction (le second paramètre) sur une valeur en contexte (le premier
>> paramètre).
>>
>> Cependant, le type donné à la fonction lui confère un potentiel différent
>> dans chaque cas:
>> - pour Applicative, la fonction qui reçoit un a n'a pas la possibilité
>> d'altérer son contexte, car la fonction est dans le contexte: c (a -> b)
>> - pour Monad, la fonction qui reçoit un a se charge de construire le
>> contexte pour son résultat: a -> c b
>>
>> Du coup, dans Applicative, la valeur de a peut seulement influencer la
>> valeur de b, mais pas la structure du contexte c.
>> Alors que dans Monad, la valeur de a peut influencer à la fois la valeur
>> de b et la structure du contexte c dans lequel b est placé.
>>
>> ---
>>
>> Dans le cas des listes :
>>
>> (<*>) :: [a -> b]  -> [a] -> [b]   -- j'ai remis les paramètres dans
>> l'ordre d'Haskell pour la suite de mon email
>> (>>=) :: [a] -> (a -> [b]) -> [b]
>>
>> Pour (fl <*> xl), quelles que soient les valeurs dans xl, la liste
>> résultante aura autant d'éléments que le produit du nombre d'éléments de fl
>> et xl. Les fonctions contenues dans fl peuvent contrôler les valeurs dans
>> la liste finale, mais pas la structure de la liste finale.
>>
>> Pour (xl >>= fl), les fonctions peuvent également affecter la structure
>> résultante.
>>
>> [1,2,3] >>= (\a -> if a == 1 then [] else [a+1, a+2])
>>
>> Ici, j'ai le droit de regarder la valeur, et de modifier la structure du
>> contexte produit (par exemple, je produis une liste vide quand la valeur
>> est 1, et une liste à deux éléments autrement).
>>
>> ---
>>
>> Dans la monade IO, c'est ce qui te permet de choisir quelles actions
>> faire en fonction du résultat produit par les actions précédentes.
>>
>> (<*>) :: IO (a -> b)  -> IO a -> IO b
>> (>>=) :: IO a -> (a -> IO b) -> IO b
>>
>> iof <*> ioa   -- quelle que soit la valeur produite par ioa, on applique
>> la fonction dans iof
>> ioa >>= (\a -> ....)   -- ici, dans les ... tu peux regarder a, et
>> effectuer différentes actions, ce qui est impossible avec Applicative
>>
>> ---
>>
>> Corrigez-moi si je dis des bêtises... je suis malade et fatigué ! :-)
>>
>> - Valentin
>>
>>
> Ça me paraît plus clair, pour être sur :
>  * une Applicative me permet de réunir inconditionnellement deux
> expression au sein d'un même contexte (une sorte de write only)
>  * une Monade me permet de lire la valeur d'un contexte et dans recréer un
> à ma guise, comme je le souhaite (une sorte de read, drop, create)
>
> Merci.
>
> _______________________________________________
> Haskell-fr mailing list
> Haskell-fr at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-fr
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-fr/attachments/20140326/c8c30dbc/attachment.html>


More information about the Haskell-fr mailing list