Je suis nouveau chez Haskell et je lis sur les foncteurs et les foncteurs applicatifs. Ok, je comprends les foncteurs et comment les utiliser, mais je ne comprends pas pourquoi les foncteurs d’ application sont utiles ni comment les utiliser en Haskell. Pouvez-vous m'expliquer avec un exemple simple pourquoi j'ai besoin de foncteurs applicatifs?
Réponses
Trop de publicités?Les foncteurs applicatifs sont une construction qui fournit le milieu entre les foncteurs et les monades, et sont donc de plus en plus répandue que les monades, tandis que plus utile que les foncteurs. Normalement, vous pouvez juste la carte d'une fonction sur un foncteur. Les foncteurs applicatifs vous permettent de prendre une fonction "normale" (compte non functorial arguments) utiliser pour opérer sur plusieurs valeurs qui sont dans foncteur contextes. En corollaire, cela vous donne effectful de programmation sans monades.
Une belle, autonome explication heurte à des exemples peuvent être trouvés ici. Vous pouvez aussi lire une pratique exemple d'analyse développé par Brian O'Sullivan, qui ne nécessite aucune connaissance préalable.
Les foncteurs applicatifs sont utiles lorsque vous avez besoin de séquençage des actions, mais n'avez pas besoin de citer tous les résultats intermédiaires. Ils sont donc plus faibles que les monades, mais plus fort que les foncteurs (ils n'ont pas explicitement lier opérateur, mais ils ne permettent d'utiliser des fonctions arbitraires à l'intérieur du foncteur).
Quand sont-ils utiles? Un exemple courant est celui de l'analyse, où vous avez besoin d'exécuter un certain nombre d'actions que lire des parties d'une structure de données dans l'ordre, puis de la colle tous les résultats ensemble. C'est comme une forme générale de la fonction de la composition:
f a b c d
où vous pouvez penser à de la a
, b
et ainsi de suite comme arbitraire des actions à exécuter, et f
comme le foncteur d'appliquer au résultat.
f <$> a <*> b <*> c <*> d
J'aime à penser à eux comme surchargé 'espace'. Ou, que régulièrement Haskell fonctions sont dans l'identité foncteur applicatif.
Voir la section "Application de la Programmation avec des Effets"
Functional Pearl, de Conor McBride et Ross Paterson, présente plusieurs exemples intéressants. Il est également responsable de la vulgarisation du style en premier lieu. Ils utilisent le terme "idiome" pour "foncteur applicatif", mais à part cela, c'est assez compréhensible.
Il est difficile de venir avec des exemples de cas où vous besoin de foncteurs applicatifs. Je peux comprendre pourquoi un intermédiaire Haskell programmeur voudrais leur demander de soi que la question puisque la plupart des textes d'introduction présente les instances issus de Monades à l'aide de Foncteurs Applicatifs seulement comme une interface pratique.
L'idée clé, comme mentionné à la fois ici et dans la plupart des introductions sur le sujet, c'est que les Foncteurs Applicatifs sont entre les Foncteurs et les Monades (même entre les Foncteurs et les Flèches). Toutes les Monades sont des Foncteurs Applicatifs, mais pas tous les Foncteurs sont Applicative.
Donc forcément, parfois, nous pouvons utiliser des applicatifs combinators pour quelque chose que nous ne pouvons pas utiliser monadique combinators pour. Une telle chose est ZipList, qui est juste un wrapper autour de la liste afin d'avoir un autre Applicatif instance, puis le dérivé de la Monade exemple de liste. L'Applicatif documentation utilise la ligne suivante pour donner une notion intuitive de ce qu'ZipList est pour:
f <$> ZipList xs1 <*> ... <*> ZipList xsn = ZipList (zipWithn f xs1 ... xsn)
Comme l'a souligné ici, il est possible de faire bizarre Monade instances de près le travail de ZipList.
Il y a d'autres Foncteurs Applicatifs qui ne sont pas des Monades (voir cette SORTE de question) et ils sont faciles à trouver. Avoir une Interface alternative pour les Monades, c'est bien joli, mais parfois faire une Monade est inefficace, complexe, voire impossible, et c'est quand vous avez besoin de Foncteurs Applicatifs.
avertissement: Faire des Foncteurs Applicatifs peuvent également être inefficace, complexe, et impossible, en cas de doute, consultez votre représentant local de catégorie théoricien de la bonne utilisation des Foncteurs Applicatifs.
Un bon exemple: application de l'analyse.
Voir [real world haskell] ch16 http://book.realworldhaskell.org/read/using-parsec.html#id652517
C'est l'analyseur de code avec la notation:
-- file: ch16/FormApp.hs
p_hex :: CharParser () Char
p_hex = do
char '%'
a <- hexDigit
b <- hexDigit
let ((d, _):_) = readHex [a,b]
return . toEnum $ d
À l'aide de foncteur de le rendre beaucoup plus courte:
-- file: ch16/FormApp.hs
a_hex = hexify <$> (char '%' *> hexDigit) <*> hexDigit
where hexify a b = toEnum . fst . head . readHex $ [a,b]
de levage peuvent se cacher les détails sous-jacents de certains répétition du code. ensuite, il vous suffit d'utiliser moins de mots pour dire l'exact et précis de l'histoire.