[Haskell-fr] Éclaircissement sur les Applicatives

Arnaud Bailly arnaud.oqube at gmail.com
Sat Dec 21 07:13:28 UTC 2013


Bonjour Gautier,

Personnellement, la lecture de ce papier
http://strictlypositive.org/IdiomLite.pdf m'a aidé à mieux comprendre les
foncteurs applicatifs. Il montre très bien que le principal intérêt de ces
structures c'est de pouvoir écrire des fonctions plus génériques, comme à
peu près toutes les structures en Haskell d'ailleurs...

Une autre chose qui m'a beaucoup aidé c'est de comprendre le système de
type de Haskell de manière plus détaillée. Tu peux voir du côté du livre de
Benjamin Pierce, par exemple. Une des portes d'entrée possible, c'est de
voir que le système de types est lui aussi fonctionnel : tu as des valeurs
(les types) et des fonctions (les constructeurs de types), ces derniers
pouvant être "currifiés". Et tu peux appliquer ces objets les uns aux
autres selon leur "genre" (kind) qui est le "système de types" des types :-)

Du coup une signature du genre:

> pure :: (Applicative f) => a -> f a

se lit simplement et donne comme indication que 'f' doit être un
constructeur de types avec un argument (de genre '* -> * pour être précis.

Concernant tes questions, je crois que les autres réponses de la liste sont
claires et que l'article dont je t'ai donné le lien t'aidera aussi. Juste
une remarque sur Q1 : il n'est question d'intérêt ici, mais d'une
obligation "contractuelle" qui rend nécessaire que 'f' soit bien un
foncteur pour permettre de construire un applicatif, simplement parce qu'un
foncteur est la brique de base permettant d'encapsuler des valeurs dans
types "conteneurs".

Cordialement,

--
Arnaud Bailly
FoldLabs Associate: http://foldlabs.com


2013/12/20 Gautier DI FOLCO <gautier.difolco at gmail.com>

> Bonjour,
>
> Cela fait maintenant quelques mois que je côtoie Haskell, j'arrive presque
> toujours à mes fins, mais cela ne me convient pas, je tente donc de prendre
> le problème à sa racine : la compréhension, ou plutôt l'assimilation des
> concepts. Je pense que j'ai un soucis à ce niveau car je pense plutôt bien
> voir comment tout s'emboîte, mais face au code, je suis incapable de
> l'appliquer ! Je vous laisse juger par vous-même.
> Je vais tenter d'expliquer ma manière de voir les choses de manière aussi
> détaillée que possible via un ensemble d'assertions (notées AN où N est le
> numéro de l'assertion).
> Le typeclass Applicative à la tête suivante :
> class Functor f => Applicative f where
>   pure :: a -> f a
>   (<*>) :: f (a -> b) -> f a -> f b
>   (*>) :: f a -> f b -> f b
>   (<*) :: f a -> f b -> f a
>
> A1 : Ce qui signifie que tout type implémentant ces fonctions doivent
> également implémenter les fonctions de Functor.
> Q1 : quelle est l'intérêt ?
>
> Nous avons pure :: Applicative f => a -> f a
> A2 : 'f a' signifie de type a implémentant le typeclass f (Applicative
> dans ce cas précis
> A3 : Il s'agit "simplement" d'un lifting, d'une encapsulation, grosso-modo
> de donner un paramètre à un constructeur.
>
> Ensuite (<*>) :: Applicative f => f (a -> b) -> f a -> f b
> A4 : prend une fonction et un paramètre dans un "emballage" implémentant
> Applicative et applique cette valeur à cette fonction en retournant le type
> dans un autre "emballage".
> A5 : cette fonction sert dans deux cas : à fournir un moyen de manipuler
> le contenu de "boîtes", "décurryfier" dans le sens passer des arguments au
> fur et à mesure à une fonction.
> Q2 : Y a-t-il d'autres cas d'application.
>
> A6 : <* et *> ne servent qu'à appliquer un des arguments.
> Q3 : quels sont les cas d'applications typiques ? j'ai du mal à voir
>
> Ensuite il y a les fonctions de lifting :
>
> liftA :: Applicative f => (a -> b) -> f a -> f b
> A7 : prend une fonction "normale" à un argument et en fait une fonction
> maniant une structure encapsulée.
> Q4 : quel est l'intérêt ? liftA (+1) $ Just 1 n'est pas égale à pure (+1)
> <*> Just 1 ?
> Q5 : ou à la version Functor : (+1) <$> Just 1 ?
> Q6 : dans le cas de version Functor, quel est l'intérêt de la passer
> Applicative ?
> liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
> A8 : idem mais avec deux arguments
> A9 : liftA2 (+) (Just 2) (Just 1) est équivalent à liftA (+) (Just 2) <*>
> Just 1
> Q7 : Quel est l'intérêt du coup ?
> liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
> A10 : idem mais avec trois arguments
>
> Q8 : Quel est l'intérêt de Control.Applicative.Lift ?
> Il est écrit : "Adding a new kind of pure computation to an applicative
> functor"
> Q9 : J'ai du mal à saisir cette notion de calcul, est-ce qu'il est
> possible de me  l'expliquer en deux mots ?
>
> Je me rend compte que mon mail est très long, ça fait plus de deux mois
> que je me casse les dents dessus, j'ai écumé plusieurs articles/livres, pas
> moyen de me faire une idée claire de tout ça, ou de voir les applications
> pratiques.
> Je vous serait très reconnaissant de prendre le temps de me répondre et/ou
> de valider/invalider mes assertions,
> Merci par avance.
>
> PS : Par la suite j'aurais des question sur Alternative et les Monades
> PPS : la longueur de la rédaction m'a donné une idée pour Q7 :
> A11 : liftA2 et liftA3 servent à obtenir des fonctions "passables" à des
> fonctions qui le demande, ex :
> myF :: (Maybe a -> Maybe b -> Maybe c) -> a -> b -> Maybe c
> myF f a b = f (Just a) (Just  b)
> la fonction serait appelable via myF (liftA2 (+)) 1 2
>
> _______________________________________________
> 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/20131221/6da6ef97/attachment-0001.html>


More information about the Haskell-fr mailing list