Die folgenden Typprüfungen:
%Vor% Ist das tatsächlich eine gültige Monad
-Instanz? Wenn ja, warum wird es nicht verwendet? Wenn nein, bricht es irgendwelche Gesetze oder solche? Ich habe nicht bewiesen, dass die Gesetze gelten, aber ich konnte auch kein Gegenbeispiel finden.
Dies sollte ein Gegenbeispiel für das richtige Identitäts-Monaden-Gesetz sein.
Im Folgenden nutzen wir das Funktor-Produkt Maybe :*: Maybe
von GHC.Generics
, aber es könnte auch inline sein, falls gewünscht. Dies ist auch eine anwendbare, alternative, faltbare und Monade. Ich vertraue darauf, dass die Bibliotheken in diesen Fällen gesetzestreu sind.
Wir vergleichen dann die vorgeschlagene instance Monad
(die in der Frage) mit der Standardbibliothek eins. Wir finden, dass das richtige Identitätsgesetz für die vorgeschlagene Instanz nicht erfüllt ist, während es scheint (zumindest in meinen sehr begrenzten Tests) in der Bibliotheksinstanz zu enthalten.
Das 4
wird jetzt durch 3
ersetzt. Ich habe jedoch nicht versucht zu erklären, warum.
Ich denke, es wird von Just 3 <|> Just 4 = Just 3
verursacht.
Mit der Library-Monad-Instanz hingegen sieht alles gut aus:
%Vor% Alternative
ist ein bisschen wie ein hacky biest. Es ist im Wesentlichen die Klasse von Monoidkonstruktoren : Typkonstruktoren T
, so dass für jeden enthaltenen Typ X
, T X
ein Monoid ist. Das hat nicht viel mit Funktoren zu tun ... Monaden, und ist mathematisch viel weniger tief. (Also, nur für mathematische Eleganz, wäre es ein bisschen schlecht, Monad
unter Alternative
zu setzen.)
Lassen Sie uns diese Instanz in Monoid
zur besseren Übersichtlichkeit schreiben (dies wird nicht wirklich kompiliert):
oder tatsächlich
%Vor%Also, das ist definitiv nicht etwas Unbekanntes.
Um die Gesetze zu überprüfen, betrachten wir am besten die Kleisli-Formulierung:
%Vor%d. h.
%Vor%Dann sind die Monadengesetze
Linke Identität
%Vor%Richtige Identität
%Vor%Assoziativität
%Vor%Kurz gesagt, wir brauchen
foldMap f . pure =! f =! foldMap pure . f
∀ f
foldMap (foldMap f . g) =! foldMap f . foldMap g
∀ f
, g
Das sieht sicherlich nicht unangemessen aus, aber ich sehe nicht, woher Sie es für willkürliche Foldable
+ Alternative
Instanzen rigoros schließen könnten.
Wirklich, das große Problem, das ich bei dieser Instanz sehe, ist, dass es nicht annähernd allgemein genug ist. Die meisten Monaden sind weder Foldable
noch Alternative
. Wenn es eine Cover-All-Definition wie die von Ihnen vorgeschlagene Definition gäbe, würde OverlappingInstances
eine eigene Instanz definieren müssen, und diese werden im Allgemeinen als etwas angesehen, das Sie nicht ohne guten Grund verwenden sollten.
Ich frage mich jedoch, ob es Probleme mit der folgenden Standard-Definition für die Bind-Methode geben würde:
%Vor%Das würde zumindest erlauben, z.B. die Listeninstanz einfach als
%Vor% ohne die Methoden überhaupt ausschreiben zu müssen, denn foldMap ≡ concatMap ≡ (=<<)
.