Gibt es einen bestimmten Grund, warum das Prelude das List-Monad nicht so definiert? (Beachten Sie die nicht standardmäßige Implementierung von >>
.)
instance Monad [] where
m >>= k = concat (map k m)
m >> k = k -- a.k.a. flip const
return x = [x]
fail s = []
Ich habe versucht, dies anhand der Monaden-Gesetze zu überprüfen, aber sie erwähnen >>
nicht. Die Definition der Monad
-Klasse ist folgende:
m >> k = m >>= \_ -> k
was in der []
-Instanz zu folgendem übersetzt würde:
concat (map (\_ -> k) m)
was natürlich nicht gleich flip const
ist - sie erzeugen offensichtlich unterschiedliche Ergebnisse für z.B. [1..5] >> return 1
. Aber es ist für mich nicht klar, ob diese Standarddefinition ein Gesetz ist, das Instanzen von Monad
beachten müssen, oder einfach eine Standardimplementierung, die ein anderes Gesetz erfüllt, das die flip const
Implementierung auch erfüllen würde.
Intuitiv scheint, angesichts des Ziels der Listenmonade ("nichtdeterministische Berechnungen"), die alternative Definition von >>
genauso gut zu sein, wenn nicht sogar besser, da durch Beschneiden von Zweigen, die garantiert gleich sind, nur einer übrig bleibt. Oder anders ausgedrückt: Wenn wir mit Mengen anstelle von Listen arbeiten würden, wären die beiden Kandidaten-Definitionen äquivalent. Aber übersehe ich hier etwas, was die flip const
-Definition falsch für Listen macht?
BEARBEITEN: Die Antwort von ehird behebt einen sehr offensichtlichen Fehler oben, nämlich dass sie das falsche beabsichtigte Ergebnis für [] >> k
erhält, das []
sein sollte, nicht k
. Dennoch denke ich, dass die Frage auf diese Definition abgeändert werden kann:
[] >> k = []
_ >> k = k