79 votes

Pourquoi devrais-je utiliser des foncteurs applicatifs en programmation fonctionnelle ?

Je suis nouveau en Haskell, et je lis sur les foncteurs et les foncteurs applicatifs. Ok, je comprends les foncteurs et comment je peux les utiliser, mais je ne comprends pas pourquoi les foncteurs applicatifs sont utiles et comment je peux les utiliser en Haskell. Pouvez-vous m'expliquer avec un exemple simple pourquoi j'ai besoin de foncteurs applicatifs ?

0 votes

Il s'agit seulement d'un lien que je peux donner, mais ici se trouve une belle description des Foncteurs Applicatifs avec des exemples.

1 votes

56voto

huitseeker Points 6049

Les foncteurs applicatifs sont une construction qui fournit le point médian entre les foncteurs et les monades, et sont donc plus répandus que les monades, tout en étant plus utiles que les foncteurs. Normalement, vous pouvez simplement mapper une fonction sur un foncteur. Les foncteurs applicatifs vous permettent de prendre une fonction "normale" (prenant des arguments non-fonctoriels) pour l'utiliser sur plusieurs valeurs qui se trouvent dans des contextes de foncteurs. Par conséquent, cela vous permet de programmer avec des effets sans utiliser des monades.

Une explication agréable et autonome, avec de nombreux exemples, peut être trouvée ici. Vous pouvez également lire un exemple pratique d'analyse syntaxique développé par Bryan O'Sullivan, qui ne nécessite aucune connaissance préalable.

3 votes

Il y a des liens utiles, mais je ne pense pas qu'ils puissent remplacer un court exemple simple axé sur la réponse à la question, avec tous les détails non pertinents supprimés autant que possible.

34voto

Don Stewart Points 94361

Les applicative functors sont utiles lorsque vous avez besoin de séquencer des actions, mais que vous n'avez pas besoin de nommer de résultats intermédiaires. Ils sont donc plus faibles que les monades, mais plus forts que les functors (ils n'ont pas d'opérateur bind explicite, mais ils permettent d'exécuter des fonctions arbitraires à l'intérieur du functor).

Quand sont-ils utiles? Un exemple courant est l'analyse syntaxique, où vous devez exécuter un certain nombre d'actions qui lisent des parties d'une structure de données dans un ordre donné, puis coller tous les résultats ensemble. C'est comme une forme générale de composition de fonctions :

f a b c d

où vous pouvez penser à a, b et ainsi de suite comme les actions arbitraires à exécuter, et f comme le functor à appliquer au résultat.

f <$> a <*> b <*> c <*> d

J'aime les considérer comme du 'blanc superchargé'. Ou, que les fonctions Haskell régulières sont dans le functor applicatif identité.

Voir "Programmation Applicative avec Effets"

12voto

John L Points 20989

Le Joyau Fonctionnel de Conor McBride et Ross Paterson sur le style comporte plusieurs bons exemples. Il est également responsable de populariser ce style en premier lieu. Ils utilisent le terme "idiom" pour "foncteur applicatif", mais à part cela, c'est assez compréhensible.

9voto

HaskellElephant Points 4985

Il est difficile de trouver des exemples où vous avez besoin de foncteurs applicatifs. Je peux comprendre pourquoi un programmeur Haskell intermédiaire se poserait cette question, car la plupart des textes d'introduction présentent des cas dérivés de Monades en utilisant uniquement des Foncteurs Applicatifs comme interface pratique.

L'idée clé, comme mentionné ici et dans la plupart des introductions au sujet, est que les Foncteurs Applicatifs se situent entre les Foncteurs et les Monades (même entre les Foncteurs et les Flèches). Toutes les Monades sont des Foncteurs Applicatifs mais tous les Foncteurs ne sont pas Applicatifs.

Par conséquent, parfois nous pouvons utiliser des combinateurs applicatifs pour quelque chose pour laquelle nous ne pouvons pas utiliser des combinateurs monadiques. Un tel exemple est ZipList (voir aussi cette question SO pour quelques détails), qui est juste un wrapper autour des listes afin d'avoir une différente instance Applicative que celle dérivée de l'instance Monad de liste. La documentation sur les Foncteurs Applicatifs utilise la ligne suivante pour donner une notion intuitive de ce que ZipList est :

f <$> ZipList xs1 <*> ... <*> ZipList xsn = ZipList (zipWithn f xs1 ... xsn)

Comme signalé ici, il est possible de créer des instances quasi-fonctionnelles de Monade qui fonctionnent presque pour ZipList.

Il existe d'autres Foncteurs Applicatifs qui ne sont pas des Monades (voir cette question SO) et ils sont faciles à trouver. Avoir une interface alternative pour les Monades est bien, mais parfois créer une Monade est inefficace, compliqué, voire impossible, et c'est à ce moment-là que vous avez besoin de Foncteurs Applicatifs.


Avertissement : Créer des Foncteurs Applicatifs pourrait également être inefficace, compliqué et impossible, en cas de doute, consultez votre théoricien de la catégorie local pour l'utilisation correcte des Foncteurs Applicatifs.

6voto

Nybble Points 1173

Un bon exemple : l'analyse applicative.

Voir [real world haskell] ch16 http://book.realworldhaskell.org/read/using-parsec.html#id652517

Voici le code du parseur avec la notation do :

-- file: ch16/FormApp.hs
p_hex :: CharParser () Char
p_hex = do
  char '%'
  a <- hexDigit
  b <- hexDigit
  let ((d, _):_) = readHex [a,b]
  return . toEnum $ d

En utilisant le foncteur pour le rendre beaucoup plus court :

-- file: ch16/FormApp.hs
a_hex = hexify <$> (char '%' *> hexDigit) <*> hexDigit
    where hexify a b = toEnum . fst . head . readHex $ [a,b]

'lifting' peut cacher les détails sous-jacents de certains codes répétitifs. alors vous pouvez simplement utiliser moins de mots pour raconter une histoire exacte et précise.

4 votes

Tu as une drôle d'idée de ce qui est "beaucoup plus court" - la version applicative est plus longue de 7 caractères!

0 votes

@Daniel Wagner: -_-||, Oh mon.. tu as une bonne compréhension du code, je dois avouer. En fait, je voulais dire 'plus court verticalement' :)

0 votes

Eh bien, cela peut être écrit plus court en utilisant des fonctions courantes de la bibliothèque Control.Monad: char '%' >> liftM (toEnum . fst . head . readHex) (replicateM 2 hexDigit).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X