
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