3 votes

Pourquoi la méthode de la monade liste pour `>>` n'est-elle pas définie comme `flip const` ?

Y a-t-il une raison pour laquelle le Prelude ne définit pas le monad list comme ceci ? (Notez l'implémentation non standard de >> .)

instance  Monad []  where
    m >>= k          = concat (map k m)
    m >> k           = k                 -- a.k.a. flip const
    return x         = [x]
    fail s           = []

J'ai essayé de vérifier cela par rapport aux lois sur les monades, mais elles ne mentionnent pas >> . Le site Monad La définition de la classe est la suivante :

m >> k = m >>= \_ -> k

qui, dans le [] se traduirait par ceci :

concat (map (\_ -> k) m)

ce qui n'est bien sûr pas équivalent à flip const -ils produisent des résultats manifestement différents pour, par exemple, [1..5] >> return 1 . Mais il n'est pas clair pour moi que cette définition par défaut soit une loi que les instances de Monad doit respecter, ou simplement une mise en œuvre par défaut qui satisfait à une autre loi que l'application flip const serait également satisfaisante.

Intuitivement, étant donné le intention de la monade liste ("calculs non déterministes"), il semble que la définition alternative de >> serait tout aussi bon, voire meilleur, grâce à l'élagage des branches qui sont garanties égales jusqu'à une seule. Ou une autre façon de dire cela est que si nous avions affaire à fixe au lieu de listes les deux définitions candidates seraient équivalentes. Mais est-ce que je manque une subtilité ici qui rend la flip const définition erronée pour les listes ?

EDITAR La réponse de ehird corrige un défaut très évident de la méthode ci-dessus, à savoir qu'elle aboutit à un résultat erroné pour la fonction [] >> k qui devrait être [] no k . Malgré tout, je pense que la question peut être modifiée en fonction de cette définition :

[] >> k = []
_ >> k = k

14voto

ehird Points 30215

a >> b doit toujours être équivalent à a >>= const b ; c'est seulement dans le Monad afin que vous puissiez définir une classe plus efficace (mais sémantiquement équivalent ). C'est la raison pour laquelle elle ne fait pas partie des lois sur les monades : elle ne fait pas vraiment partie de la définition d'une monade, mais uniquement de la classe de type (comme fail ).

Malheureusement, je ne trouve nulle part dans la documentation du paquet de base où cela est explicitement indiqué, mais je pense que les anciennes versions ont pu définir (>>) en dehors de la Monad typeclass.

Pour ce que ça vaut, votre définition de (>>) casse l'utilisation de la monade liste pour les calculs non déterministes. Puisque [] est utilisé pour représenter l'échec, [] >> m doit toujours être [] ; on ne peut pas continuer après avoir épuisé toutes les branches possibles ! Cela voudrait aussi dire que ces deux programmes :

do { m; ... }
do { _ <- m; ... }

pourraient différer en termes de comportement, puisque le premier désugarise avec le (>>) et ce dernier avec (>>=) . (Voir le Rapport sur Haskell 2010 .)

4voto

ben w Points 1851

Parce que ma >> mb juste est un raccourci pour ma >>= \_ -> mb . Si >> ont été définis comme suit flip const juste dans le cas des listes, alors ma >> mb n'aurait pas exécuté le calcul dans ma du tout si ma est une liste, ce qui serait très déroutant.

Quant à savoir pourquoi il n'est pas défini comme flip const en général et bien, la sémantique actuelle de >> lui permet de séquencer des effets dont le résultat ne vous intéresse pas, ce qui est souvent utile.

2voto

pat Points 6761

Votre définition de >> brise le Monad loi d'associativité :

newtype B a = B { unB :: [a] }

instance Monad B where
  m >>= f = B . concatMap (unB.f) $ unB m
  (>>) = flip const
  return a = B [a]

case1 = B [1,2,3] >>= (\_ -> B [4,5,6] >> return 1)
case2 = (B [1,2,3] >>= \_ -> B [4,5,6]) >> return 1

main = do
  print $ unB case1
  print $ unB case2

Les deux cas ci-dessus diffèrent par leur associativité, mais donnent des résultats différents.

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