41 votes

Pourquoi MonadPlus et non Monad + Monoid ?

J'essaye de comprendre la motivation derrière la MonadPlus . Pourquoi est-ce nécessaire s'il existe déjà des classes de type Monad et Monoid ?

Accordé, les instances de Monoid sont des types concrets, tandis que les instances de Monad nécessitent un seul paramètre de type. (Voir Monoïde et MonadPlus pour une explication utile). Mais ne pouvez-vous pas réécrire toute contrainte de type de

(MonadPlus m) => ...

comme une combinaison de Monad et Monoid ?

(Monad m, Monoid (m a)) => ...

Prenez le guard de la fonction Control.Monad par exemple. Sa mise en œuvre est :

guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero

J'ai pu l'implémenter en utilisant seulement Monad et Monoid :

guard' :: (Monad m, Monoid (m ())) => Bool -> m ()
guard' True = return ()
guard' False = mempty

Quelqu'un pourrait-il clarifier la différence réelle entre MonadPlus et Monad + Monoid ?

38voto

Toxaris Points 3265

Mais ne pourriez-vous pas réécrire toute contrainte de type de

(MonadPlus m) => ...

comme une combinaison de Monad et Monoid ?

Non. Dans la première réponse à la question que vous mettez en lien, il y a déjà une bonne explication sur les lois de MonadPlus vs Monoid. Mais même si nous ignorons les lois de la classe de type, il y a des différences.

Monoid (m a) => ... signifie que m a doit être un monoïde pour une raison particulière a choisi par l'appelant, mais MonadPlus m signifie que m a doit être un monoïde pour tous les a . Donc MonadPlus a est plus flexible, et cette flexibilité est utile dans quatre situations :

  1. Si nous ne voulons pas dire à l'appelant ce que a que nous avons l'intention d'utiliser.
    MonadPlus m => ... au lieu de Monoid (m SecretType) => ...

  2. Si nous voulons utiliser plusieurs a .
    MonadPlus m => ... au lieu de (Monoid (m Type1), Monoid (m Type2), ...) => ...

  3. Si nous voulons utiliser une infinité de différents a .
    MonadPlus m => ... au lieu de pas possible.

  4. Si nous ne savons pas ce que a nous avons besoin. MonadPlus m => ... au lieu de pas possible.

6voto

Sassa NF Points 3181

Votre guard' ne correspond pas à votre Monoid m a type.

Si vous voulez dire Monoid (m a) alors vous devez définir ce que mempty est pour m () . Une fois que vous avez fait cela, vous avez défini une MonadPlus .

En d'autres termes, MonadPlus définit deux opérations : mzero et mplus satisfaisant à deux règles : mzero est neutre par rapport à mplus et mplus est associatif. Cela répond à la définition d'un Monoid de sorte que mzero est mempty et mplus est mappend .

La différence est que MonadPlus m est un monoïde m a pour tout a mais Monoid m définit un monoïde uniquement pour m . Votre guard' fonctionne parce que vous avez seulement besoin m pour être un Monoid seulement pour () . Mais MonadPlus est plus forte, elle affirme m a pour être un monoïde pour tout a .

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