Warum kompiliert dieses äquivalente Programm nicht?

8

Dieses Programm:

%Vor%

Kompiliert. Dieses Programm:

%Vor%

Kompiliert nicht mit dem folgenden Fehler:

%Vor%

Warum?

    
MaiaVictor 05.09.2015, 20:47
quelle

2 Antworten

3

Hinweis: Dieser Beitrag ist in literarischem Haskell geschrieben. Sie können es als Unsafe.lhs speichern und es in Ihrem GHCi versuchen.

Vergleichen wir die Typen der verschiedenen Zeilen:

%Vor%

Sie sind aufgrund des Typs $ nicht gleichwertig:

%Vor%

Während Sie etwas brauchen würden

%Vor%

was nicht legal ist.

Sehen wir uns jedoch an, was Sie eigentlich tun wollen.

%Vor%

Die Dinge wurden aufgrund des polymorphen ersten Arguments unsafeModify mods unordentlich. Dein ursprünglicher Typ

%Vor%

sagt uns, dass es sich um eine Liste von Funktionen handelt, bei denen jede Funktion polymorph ist und der Parameter s , so dass jede Funktion ein anderes s verwenden kann. Das ist jedoch zu viel. Es ist in Ordnung, wenn das s über die gesamte Liste geteilt wird:

%Vor%

Schließlich wollen wir alle Funktionen in der gleichen ST Berechnung verwenden, daher kann der Typ des Stromstatus-Tokens s gleich sein. Wir enden mit

%Vor%

Und nun kompiliert Ihr Code glücklich, unabhängig davon, ob Sie ($ mvec) (mods !! 0) , (mods !! 0) mvec oder mapM_ verwenden, weil s jetzt korrekt durch runST in der gesamten Liste korrigiert wird.

    
Zeta 06.09.2015, 05:46
quelle
3

(Dies sollte wahrscheinlich ein Kommentar sein, aber ich brauche mehr Platz.)

Leider funktionieren impredikative Typen in GHC nicht sehr gut, wie @dfeuer betonte. Betrachten Sie dieses Beispiel:

%Vor%

Es kompiliert erfolgreich, wenn auch mit einer Warnung wegen des Typs Loch:

%Vor%

Wir könnten versuchen, die Erweiterung PartialTypeSignatures zu entfernen und die Lücke mit ihrem Typ forall s. MV.MVector s Int -> ST s () zu füllen. Aber das scheitert schrecklich:

%Vor%

Der letzte forall wird auf die oberste Ebene gehievt, und nun sagt GHC, dass das erste Argument von (!!) eine Liste monomorpher Elemente sein muss [MV.MVector s1 Int -> ST s1 ()] trotz unserer Annotation! Grundsätzlich hat GHC zwei Möglichkeiten:

%Vor%

GHC wählt die zweite und schlägt fehl. Nur mit einer partiellen Typ-Signatur konnte ich die zweite Wahl entfernen, so dass GHC gezwungen war, das Richtige zu tun.

Wenn wir nur eine explizite Anwendung wie in GHC Core hätten, hätten wir (!!) @ (forall s. ...) schreiben können, aber leider nicht.

    
chi 06.09.2015 06:01
quelle

Tags und Links