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