Die Standard-Bibliothek Haskell typeclasses MonadPlus
, Alternative
und Monoid
liefern jeweils zwei Verfahren mit im Wesentlichen gleicher Semantik:
- Ein leerer Wert:
mzero
,empty
odermempty
. - Eine Bedienungsperson,
a -> a -> a
die Werte in der typeclass miteinander verbindet:mplus
,<|>
, odermappend
.
Alle drei spezifizieren diese Gesetze, an die sich Instanzen halten sollten:
mempty `mappend` x = x
x `mappend` mempty = x
Es scheint also, dass die drei Typklassen alle die gleichen Methoden bereitstellen .
( Alternative
bietet auch some
und many
, aber ihre Standarddefinitionen sind normalerweise ausreichend und daher für diese Frage nicht allzu wichtig.)
Meine Frage lautet also: Warum haben diese drei extrem ähnlichen Klassen? Gibt es einen wirklichen Unterschied zwischen ihnen, abgesehen von ihren unterschiedlichen Einschränkungen der Oberklasse?
Applicative
undMonadPlus
scheinen genau gleich zu sein (Modulo-Superklassen-Einschränkungen).ArrowZero
undArrowPlus
für Pfeile. Meine Wette: Typensignaturen sauberer zu machen (was unterschiedliche Einschränkungen der Oberklasse zum wirklichen Unterschied macht).ArrowZero
undArrowPlus
hat Art* -> * -> *
, welche Mittel Sie sie in für den Pfeiltyp einmal für eine Funktion , die Bedürfnisse sie für eine Vielzahl von Typen verwenden passieren können, ein verwendenMonoid
Sie eine Instanz verlangen müßtenMonoid
für jeden einzelnen Instanziierung, und Sie hätten keine Garantie, dass sie auf ähnliche Weise behandelt wurden, die Instanzen könnten nicht miteinander zusammenhängen!Antworten:
MonadPlus
undMonoid
dienen verschiedenen Zwecken.A
Monoid
wird über eine Art von Art parametrisiert*
.und so kann es für fast jeden Typ instanziiert werden, für den es einen offensichtlichen Operator gibt, der assoziativ ist und der eine Einheit hat.
Doch
MonadPlus
nicht nur gibt an, dass Sie eine monoidal Struktur, sondern auch , dass diese Struktur auf , wie die in Beziehung stehtMonad
funktioniert, und dass diese Struktur nicht über den Wert schert in der Monade enthalten ist , das ist (teilweise ) , die durch die Tatsache , dasMonadPlus
braucht ein Argument der Art* -> *
.Zusätzlich zu den monoiden Gesetzen gibt es zwei mögliche Gesetze, auf die wir uns anwenden können
MonadPlus
. Leider ist sich die Community nicht einig, was sie sein sollte.Zumindest wissen wir es
Es gibt jedoch zwei weitere konkurrierende Erweiterungen, das linke (sic) Verteilungsgesetz
und das linke Fanggesetz
Daher sollte jeder Fall
MonadPlus
eines oder beide dieser zusätzlichen Gesetze erfüllen.Was ist also
Alternative
?Applicative
wurde nach definiertMonad
und gehört logischerweise als Oberklasse vonMonad
, aber hauptsächlich aufgrund des unterschiedlichen Drucks auf die Designer in Haskell 98,Functor
warMonad
bis 2015 nicht einmal eine Oberklasse von . Jetzt haben wir endlichApplicative
als Oberklasse vonMonad
in GHC (wenn nicht noch in einem Sprachstandard.)Effektiv
Alternative
ist zuApplicative
wasMonadPlus
ist zuMonad
.Für diese würden wir bekommen
analog zu dem, was wir haben
MonadPlus
und es gibt ähnliche Verteilungs- und Fangeigenschaften, von denen Sie mindestens eine erfüllen sollten.Leider ist auch das
empty <*> m = empty
Recht ein zu starker Anspruch. Es gilt zum Beispiel nicht für Rückwärts !Wenn wir uns MonadPlus ansehen, wird uns fast das leere >> = f = leere Gesetz aufgezwungen. Die leere Konstruktion kann
f
sowieso kein 'a' enthalten, um die Funktion aufzurufen.Da jedoch
Applicative
ist nicht eine übergeordnete Klasse vonMonad
undAlternative
ist nicht eine übergeordnete Klasse vonMonadPlus
, wickeln wir separat beiden Instanzen bis zu definieren.Selbst wenn
Applicative
es eine Superklasse von wäreMonad
, würden Sie dieMonadPlus
Klasse sowieso brauchen , denn selbst wenn wir gehorchen würdendas ist nicht streng genug, um das zu beweisen
Die Behauptung, dass etwas ein
MonadPlus
ist, ist stärker als die Behauptung, dass es ein istAlternative
.Konventionell sollte das
MonadPlus
undAlternative
für einen bestimmten Typ übereinstimmen, aber dasMonoid
kann völlig anders sein.Zum Beispiel das
MonadPlus
undAlternative
fürMaybe
das Offensichtliche tun:aber die
Monoid
Instanz hebt eine Halbgruppe in eineMonoid
. Da esSemigroup
zu diesem Zeitpunkt in Haskell 98 noch keine Klasse gab, wird leider eine Klasse angefordertMonoid
, deren Einheit jedoch nicht verwendet. ಠ_ಠTL; DR
MonadPlus
ist eine stärkere Behauptung alsAlternative
, was wiederum eine stärkere Behauptung ist alsMonoid
, und während dieMonadPlus
undAlternative
Instanzen für einen Typ in Beziehung gesetzt werden sollten,Monoid
kann (und ist manchmal) etwas völlig anderes sein.quelle
mempty `mappend` x ≡ x
.MonadPlus
undAlternative
Implementierungen hat?Monad
ist,Alternative
aber keineMonadPlus
. Ich stellte eine Frage, um ein konkretes Beispiel dafür zu finden. Wenn Sie eines kennen, würde ich es gerne sehen.MonadPlus
sind wirklich zwei Klassen als eine getarnt, weil es den meisten Menschen egal ist.