Betrachten Sie das folgende Beispielprogramm:
%Vor% Es kann nur get
anstelle von lift get
verwendet werden, weil instance MonadState s m => MonadState s (MaybeT m)
im MaybetT-Modul definiert ist.
Viele solcher Instanzen sind in Art einer kombinatorischen Explosionsmethode definiert.
Es wäre nett gewesen (obwohl unmöglich? Warum?), wenn wir die folgende Typklasse hätten:
%Vor%Versuchen wir, es so zu definieren:
%Vor% Die Verwendung von lifts $ print i
anstelle von liftIO $ print i
funktioniert, das ist nett.
Aber die Verwendung von lifts (get :: StateT Int IO Int)
anstelle von (get :: MaybeT (StateT Int IO) Int)
funktioniert nicht.
GHC (6.10.3) gibt den folgenden Fehler:
%Vor% Ich kann sehen, warum " instance SuperMonad a a
" gilt. Aber warum denkt GHC, dass der andere es auch tut?
Um die ausgezeichnete Antwort von ephemient weiter zu verfolgen: Haskell-Klassen verwenden eine Open-World-Annahme : ein Idiot kann später kommen und eine Instanzdeklaration hinzufügen, die kein Duplikat ist überlappt sich jedoch mit Ihrer Instanz. Betrachte es als ein Gegnerspiel : Wenn ein Gegner dein Programm mehrdeutig machen kann, blökt der Compiler.
Wenn Sie GHC verwenden, können Sie natürlich dem Compiler sagen "Zur Hölle mit Ihrer Paranoia; erlauben Sie mir meine mehrdeutige Instanz Deklaration":
%Vor%Wenn eine spätere Entwicklung Ihres Programms zu einer Überladungsauflösung führt, die Sie nicht erwartet haben, erhält der Compiler 1.000 I-thought-you-so Punkte: -)
Nur weil Sie in Ihrem aktuellen Modul keine Instanz definiert haben, bedeutet das nicht, dass Sie nicht anderswo definiert werden könnten.
%Vor% Angenommen, Ihr Modul und SomeOtherModule
sind in einem einzigen Programm miteinander verknüpft.
Nun, beantworte das: benutzt dein Code
%Vor%oder
%Vor%?