Haskell: Überlappende Instanzen

8

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?

    
yairchu 30.06.2009, 15:10
quelle

2 Antworten

35

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: -)

    
Norman Ramsey 02.07.2009, 04:38
quelle
8

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%

?

    
ephemient 30.06.2009 16:55
quelle

Tags und Links