TL; DR: Historische Gründe. Es wurde dies in MonadPlus
vorgesehen, das später seine Applicative
Variante Alternative
erhielt, und niemand hat vorgeschlagen, Alternative
in AZero
und AChoice
oder ähnlich zu teilen.
Alternative
ist eine relativ neue Idee, wie Applicative
. Damals, als guard
zum ersten Mal ins Auge gefasst wurde, basierte es auf MonadPlus
, einem Monad
, der Auswahl und Ausfall unterstützen sollte, genau wie Alternative
. Sein ursprünglicher Typ war so
guard :: MonadPlus m => Bool -> m()
, die in der Haskell 98 Bericht angegeben wurden, wo MonadPlus
wurde bereits erwähnt. Haskell 1.0 hat übrigens überhaupt keine Monaden benutzt. Wenn Applicative
schließlich eine Oberklasse von Monad
, Alternative
bekam bekam eine Oberklasse von MonadPlus
und mzero = empty
und mplus = (<|>)
.
Nun, jetzt wissen wir, warum guard
Alternative
verwendet. Weil es vorher auf MonadPlus
basierte. Warum ist MonadPlus
so definiert?
Man müßte eine Mail an SPJ oder jemanden anderen aus dem Komitee schreiben ihre Begründung bekommen von 1998, denn nur ein Jahr später, Erik Meijer and Graham Hutton wrote their "Monadic Parsing in Haskell" Papier. Wenn Sie einen Blick auf dem Papier haben, werden Sie feststellen, dass ihreMonadPlus
wie Sie arbeiten beabsichtigen:
class Monad m => MonadZero m where
zero :: m a
class MonadZero m => MonadPlus m where
(++) :: m a -> m a -> m a
So ist es durchaus möglich, diese „arretierbar“ die Art und Weise zu handhaben Sie haben beschrieb es. Es gibt jedoch einfach keine Klasse base
, die derzeit empty
ohne Alternative
definiert. Es könnte einen geben, aber es wurde noch nicht vorgeschlagen.
Beachten Sie, dass dies ein wiederkehrendes Thema mit Haskell-Klassen ist. Monoid
enthält mappend
und mempty
. Nach seiner Konzeption bemerkte jemand, dass es bestimmte Arten gibt, bei denen mappend
Sinn macht, aber nicht mempty
. Hier zum Beispiel
newtype Min a = Min a
combine :: Ord a => Min a -> Min a -> Min a
combine (Min x) (Min y) = Min (min x y)
ist mappend = combine
klar assoziativ, während ein leeres Min
nicht möglich ist, wenn wir nur Ord
verwenden, würden wir Bounded
verwenden. Deshalb gibt es jetzt Semigroup
, was noch keine Basisklasse von Monoid
ist, aber uns diese assoziative Operation gibt.
Um wieder auf Ihre ursprüngliche Frage zu kommen: guard
Alternative
verwendet, weil Alternative
empty
bietet, und empty
"hält" die Auswertung in bestimmten Alternative
‚s. Es gibt keine andere Klasse, die das enthält, noch.
Aber mit einem Vorschlag, könnte es irgendwann sein, obwohl ich nicht sicher bin, was die Meinung der Gemeinschaft zum Teilen Alternative
ist.
By the way, Sprachen wie PURESCRIPT gespalten Alternative
, obwohl sie es umgekehrt aufgeteilt ...
Weitere Informationen zu Alternative
und warum ich Monoid
als ein weiteres Beispiel verwendet, Confused by the meaning of the 'Alternative' type class and its relationship to other type classes sehen.
Sie brauchen auch 'pure'. Sicher, du könntest eine 'Pure' Klasse haben, die' pure' anbietet, und eine 'Empty' Klasse, die' empty' liefert und 'Alternative' benötigt beide. Aus pragmatischen Gründen wird jedoch eine Klasse nicht immer in Klassen mit einer einzigen Methode aufgeteilt. – chi
Pragmatische oder historische Gründe in diesem Fall? – gallais
Ich denke es liegt daran, dass es keine Typen gibt, die 'empty' implementieren können und' (<|>) '' nicht implementieren können. Also, theoretisch ist eine Typklasse "Stoppable" gleich "Alternative" (Satz von Typen wird gleich sein). – freestyle