60 votes

Comment utilisez-vous Control.Applicative pour écrire le nettoyeur Haskell?

Dans une récente réponse à une question style, je l'ai écrit

main = untilM (isCorrect 42) (read `liftM` getLine)

et

isCorrect num guess =
  case compare num guess of
    EQ -> putStrLn "You Win!" >> return True
    ...

Martijn a obligeamment proposé des solutions de rechange:

main = untilM (isCorrect 42) (read <$> getLine)

EQ -> True <$ putStrLn "You Win!"

Qui des tendances communes dans le code Haskell peut être rendue plus claire à l'aide d'abstractions de Contrôle.Applicative? Ce sont utiles règles de base à garder à l'esprit pour l'utilisation de la commande.Applicatifs de manière efficace?

48voto

Tony Morris Points 2304

Il y a beaucoup à dire en réponse à votre question, cependant, puisque vous le demandez, je vais proposer cette "règle du pouce."

Si vous utilisez do-notation et de vos valeurs générées[1] ne sont pas utilisés dans les expressions que vous êtes séquençage[1], alors que le code peut se transformer en un Applicatif de style. De même, si vous utilisez une ou plusieurs des valeurs générées dans une expression qui est séquencé, alors vous devez utiliser Monad et Applicative n'est pas assez forte pour atteindre le même code.

Par exemple, regardons le code suivant:

do a <- e1
   b <- e2
   c <- e3
   return (f a b c)

Nous voyons que, dans aucune des expressions à droite de l' <- effectuez l'une des valeurs générées (a, b, c) apparaissent. Par conséquent, nous pouvons le transformer à l'aide de code Applicatif. Voici l'une des transformations possibles:

f <$> e1 <*> e2 <*> e3

et un autre:

liftA3 f e1 e2 e3

Sur l'autre main, prenez ce morceau de code par exemple:

do a <- e1
   b <- e2 a
   c <- e3
   return (f b c)

Ce code ne peut pas utiliser Applicative[3] en raison de la valeur générée a est utilisé plus tard dans une expression dans la compréhension. Ce doit utiliser Monad pour arriver à son résultat -- tenter d'en tenir compte dans Applicative pour avoir une idée de pourquoi.

Il y a quelques intéressant et utile de détails à ce sujet, cependant, je viens de vous donner, cette règle générale en vertu de laquelle vous pouvez évoquer do-de la compréhension et de déterminer assez rapidement si elle peut être prise en compte dans Applicative code de style.

[1] Ceux qui apparaissent à gauche de l' <-.

[2] les Expressions qui apparaissent à droite de l' <-.

[3] à proprement parler, certaines parties pourraient, en donnant la e2 a.

44voto

Wei Hu Points 1337

Fondamentalement, les monades sont également foncteurs applicatifs [1]. Donc, chaque fois que vous vous trouvez à l'aide de liftM, liftM2, etc., vous pourriez le calcul de la chaîne d'ensemble à l'aide d' <*>. Dans un certain sens, vous pouvez penser à des foncteurs applicatifs comme analogue pour les fonctions. Une fonction pure, f peut être levée par faire f <$> x <*> y <*> z.

Par rapport à monades, les foncteurs applicatifs ne peut pas exécuter ses arguments de manière sélective. Les effets secondaires de tous les arguments qui aura lieu.

import Control.Applicative

ifte condition trueClause falseClause = do
  c <- condition
  if c then trueClause else falseClause

x = ifte (return True) (putStrLn "True") (putStrLn "False")

ifte' condition trueClause falseClause = 
  if condition then trueClause else falseClause

y = ifte' <$> (pure True) <*> (putStrLn "True") <*> (putStrLn "False")

x seulement des sorties True, alors que y sorties True et False séquentiellement.

[1] Le Typeclassopedia. Fortement recommandé.

[2] http://www.soi.city.ac.uk/~ross/papers/Applicative.html. Bien que ce soit un document universitaire, il n'est pas difficile à suivre.

[3] http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors. Explique l'affaire très bien.

[4] http://book.realworldhaskell.org/read/using-parsec.html#id652399. Montre comment le monadique Parsec bibliothèque peut également être utilisé dans une application.

10voto

Greg Bacon Points 50449

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