42 votes

Comment identifiez-vous les modèles de conception monadiques?

J'ai ma façon d'apprendre Haskell, je commence à saisir le concept de monade et de commencer à utiliser le connu monades dans mon code mais je suis toujours avoir des difficultés à approcher les monades à partir d'un concepteur de point de vue. Dans OO il y a plusieurs règles comme, "identifier les noms" pour les objets, montre une certaine forme d'état et l'interface... mais je ne suis pas en mesure de trouver des ressources équivalentes pour les monades.

Alors, comment faites-vous pour identifier un problème que monadique dans la nature? Quels sont les bons modèles de conception pour la conception monadique? Quelle est votre approche lorsque vous vous rendez compte que certains de code serait mieux remaniée dans une monade?

59voto

ehird Points 30215

En règle générale, c'est quand vous voyez des valeurs dans un contexte; monades peut être vu comme la superposition des "effets" sur:

  • Peut-être: la partialité (utilise: calculs qui peuvent échouer)
  • Soit: court-circuit des erreurs (utilise: erreur/exception)
  • [] (la liste monade): non-déterminisme (utilise: la génération de liste, filtrage, ...)
  • État: un seul mutable référence (utilise: état)
  • Lecteur: un environnement partagé (utilise: variable, fixations, commune d'information, ...)
  • Écrivain: un "canal latéral" de la sortie ou de l'accumulation (utilise: enregistrement, le maintien d'une écriture seule compteur, ...)
  • Cont: non-local de flux de contrôle (utilise: trop nombreux pour être énumérés)

Habituellement, vous devez généralement la conception de votre monade par superposition sur la monade transformateurs de la norme Monade Transformateur de la Bibliothèque, qui vous permettent de combiner les effets ci-dessus en une seule monade. Ensemble, ils gèrent la majorité des monades vous souhaitez utiliser. Il y a quelques autres monades pas inclus dans la MTL, tels que la probabilité et de l'approvisionnement des monades.

Aussi loin que l'élaboration d'une intuition pour savoir si une nouvelle définition de type est une monade, et comment il se comporte comme un seul, vous pouvez penser à elle en remontant de Functor de Monad:

  • Foncteur vous permet de transformer des valeurs avec des fonctions pures.
  • Applicative permet d'intégrer pur valeurs et à la demande expresse - (<*>) vous permet de passer d'une fonction intégrée et embarqué argument intégré à la suite.
  • Monade permet à la structure intégrée de calculs dépendent des valeurs des calculs précédents.

La meilleure façon de comprendre cela est de regarder le type d' join:

join :: (Monad m) => m (m a) -> m a

Cela signifie que si vous avez intégré de calcul dont le résultat est une nouvelle intégré de calcul, vous pouvez créer un calcul qui exécute le résultat de ce calcul. Ainsi, vous pouvez utiliser monadique effets pour créer un nouveau calcul fondé sur les valeurs de calculs précédents, et de transfert de flux de contrôle pour que le calcul.

Fait intéressant, cela peut être une faiblesse de la structuration des choses monadically: avec Applicative, la structure du calcul est statique (c'est à dire un Applicative calcul a une certaine structure, des effets qui ne peuvent changer en fonction des valeurs intermédiaires), alors qu'avec Monad il est dynamique. Cela peut limiter l'optimisation que vous pouvez faire; par exemple, applicative analyseurs sont moins puissants que monadique (le bien, ce n'est pas strictement vrai, mais il est effectivement), mais ils peuvent être optimisés mieux.

Notez que (>>=) peut être définie comme

m >>= f = join (fmap f m)

et donc, une monade peut être défini simplement avec de l' return et join (en supposant que c'est un Functor; toutes les monades sont des foncteurs applicatifs, mais Haskell typeclass hiérarchie, malheureusement, n'a pas besoin de ce pour des raisons historiques).

Comme une note supplémentaire, vous ne devriez pas se concentrer trop sur les monades, peu importe quel genre de buzz qu'ils reçoivent de l'erronées de la non-Haskellers. Il y a beaucoup de typeclasses qui représentent significatif et puissant des modèles, et non pas tout ce qui a le mieux exprimé comme une monade. Applicative, Monoïde, Pliable... qui d'abstraction à utiliser dépend entièrement de votre situation. Et, bien sûr, juste parce que quelque chose est une monade ne veut pas dire qu'il ne peut pas être d'autres choses aussi; le fait d'être une monade est juste une autre propriété d'un type.

Donc, vous ne devriez pas trop penser à "l'identification des monades"; les questions sont plus du genre:

  • Peut ce code sera exprimé plus simple monadique forme? Avec qui monade?
  • C'est ce type que j'ai donc défini une monade? Que des modèles génériques codées par les fonctions standard sur les monades puis-je profiter de la?

15voto

dave4420 Points 31298

Suivez les types.

Si vous trouvez que vous avez écrit des fonctions avec tous ces types

  • (a -> b) -> YourType a -> YourType b
  • a -> YourType a
  • YourType (YourType a) -> YourType a

ou tous ces types

  • a -> YourType a
  • YourType a -> (a -> YourType b) -> YourType b

ensuite, YourType peut être une monade. (Je dis "peut" parce que les fonctions doivent obéir à la monade lois.)

(N'oubliez pas que vous pouvez réorganiser les arguments, donc, par exemple, YourType a -> (a -> b) -> YourType b est juste (a -> b) -> YourType a -> YourType b dans le déguisement.)

Ne regardez pas seulement pour les monades! Si vous avez des fonctions de tous ces types

  • YourType
  • YourType -> YourType -> YourType

et ils obéissent à la monoïde vigueur, vous disposez d'un monoïde! Qui peut être aussi utile. De même pour les autres typeclasses, le plus important Foncteur.

7voto

stephen tetley Points 3622

Il y a l'affichage de l'effet de monades:

  • Peut - être, de la partialité ou l'échec de court-circuit
  • Soit - rapport d'erreur / de court-circuit (comme Peut-être avec plus d'informations)
  • L'écrivain - écriture seule "état", communément journalisation
  • Lecteur - read-only état, couramment de l'environnement en passant
  • L'état de lecture / écriture de l'état
  • Reprise - pausable calcul
  • Liste - de nombreuses réussites

Une fois que vous êtes familier avec ces effets, il est facile de construire des monades en les combinant avec monade transformateurs. Notez que la combinaison de certains monades besoin de soins spéciaux (en particulier Suite et de toutes les monades avec backtracking).

Une chose importante à noter, il n'y a pas beaucoup de monades. Il y a quelques exotiques qui ne sont pas dans les bibliothèques standard de l'e.g la probabilité monade et les variations de la Suite monade comme Codensity. Mais, sauf si vous faites quelque chose de mathématique, son peu probable que vous inventer (ou de découvrir) une nouvelle monade, toutefois, si vous utilisez Haskell assez longtemps, vous allez construire de nombreux monades qui sont des combinaisons différentes de la norme, celles.

Edit Également noter que l'ordre de la pile monade transformateurs résultats dans les différents monades:

Si vous ajoutez ErrorT (transformateur) pour un Écrivain monade, vous bénéficiez de cette monade Either err (log,a) - vous ne pouvez accéder à l'historique si vous n'avez pas d'erreur.

Si vous ajoutez WriterT (transfomer) à une Erreur de la monade, vous bénéficiez de cette monade (log, Either err a) qui donne toujours accès au journal.

4voto

Dan Burton Points 26639

C'est une sorte de non-réponse, mais je pense qu'il est important de dire que, de toute façon. Il suffit de demander! StackOverflow, /r/haskell, et le #haskell canal irc sont tous d'excellents endroits pour obtenir des commentaires rapides des gens intelligents. Si vous travaillez sur un problème, et vous pensez qu'il y a quelques monadique de la magie qui pourrait le rendre plus facile, il suffit de demander! Le Haskell communauté aime résoudre les problèmes, et est incroyablement sympathique.

Ne vous méprenez pas, je ne suis pas de vous encourager à ne jamais apprendre par vous-même. Bien au contraire, l'interaction avec le Haskell communauté est l'une des meilleures façons d'apprendre. LYAH et RWH, 2 Haskell livres qui sont librement disponibles en ligne, sont hautement recommandés.

Oh, et n'oubliez pas de jouer, jouer, jouer! Comme vous le jouer avec monadique code, vous allez commencer à obtenir la sensation de ce que la "forme" monades ont, et quand monadique combinators peut être utile. Si vous êtes à rouler votre propre monade, puis généralement le type de système vous guidera à une évidente, la solution la plus simple. Mais pour être honnête, vous devriez rarement pour rouler votre propre instance de Monad, depuis Haskell bibliothèques fournissent des tonnes de choses utiles comme mentionné par d'autres answerers.

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