2012-04-28 8 views
5

Ich bin neugierig auf die Einwände gegen implicit parameters in der Functional Pearl: Implicit Configurations Artikel von Kiselyov und Shan diskutiert.Sind implizite Parameter eine Schwierigkeit beim GHC?

Inline-Code (& bgr; -Reduzierung) bei Vorhandensein impliziter Parameter ist nicht vernünftig.

Wirklich? Ich würde erwarten, dass GHC in den gleichen Umfang wie der übergebene implizite Parameter eingebunden werden sollte, nein?

Ich glaube, ich ihr Einwand verstehen, dass:

ein Verhalten der Begriff kann sich ändern, wenn seine Unterschrift hinzugefügt, entfernt oder geändert werden.

GHC der Benutzerdokumentation erklärt, dass programers Pflege rund um polymorphic recursion und monomorphism restriction nehmen müssen. Ist das irgendwie ein Problem beim Inlining?

Ich vermute, dass diese polymorphe Rekursion Beispiel deckt, was sie bedeuten, indem sie "über implizite Parameter verallgemeinern"? Noch etwas? Ist die ReifiesStorable Typenklasse von Data.Reflection wirklich eine vernünftige Lösung für diese Schwierigkeiten? Es deserialisiert scheinbar die gesamte implizite Datenstruktur bei jedem Zugriff, was für die Performance katastrophal klingt. Wir könnten zum Beispiel wollen, dass unsere implizite Information eine Cayley-Tabelle oder Zeichentabelle ist, die einen Gig von Ram belegt und während Millionen von algebraischen Operationen zugänglich sein muss.

Gibt es vielleicht eine bessere Lösung, die implizite Parameter verwendet, oder eine andere Technik, die der Compiler hinter den Kulissen leicht optimieren kann, während immer noch mehr über das Typsystem mit State-Threads oder was auch immer garantiert wird?

Antwort

7

Ja, das Beispiel aus dem GHC-Handbuch zeigt, wie das Hinzufügen einer Typsignatur die Semantik des Codes mit impliziten Parametern ändern kann, und ich glaube, das ist es, was sie meinen, indem Sie inlining brechen; Inlining einer Anwendung von len_acc1 vs eine Anwendung von len_acc2 produziert den gleichen Code, trotz der beiden mit unterschiedlicher Semantik.

Soweit generalisierte über implizite Parameter bedeutet, dass Sie nicht eine Funktion schreiben können, die auf mehrere implizite Parameter arbeiten kann; Es gibt keinen Mechanismus, um über sie zu abstrahieren, da der implizite Parameter, den eine Funktion verwendet, durch ihren Typ festgelegt ist. Mit Reflection können Sie einfach eine Funktion wie doSomethingWith :: (Reifies s a, Num a) => Proxy s -> a schreiben, die über jeden Typ operieren kann, der einen numerischen Wert enthält.

Wie für ReifiesStorable, betrachten Sie eine alte Version des Reflexionspakets; Die latest version hat eine sehr effiziente Implementierung, bei der reify nur so viel kostet wie ein Funktionsaufruf. Beachten Sie, dass Sie selbst mit der alten Implementierung die Klasse ReifiesStorable nicht direkt verwenden würden, sondern stattdessen Reifies, die ReifiesStorable verwendet, um eine StablePtr zu vereinheitlichen, sodass nur ein paar Bytes kopiert werden, nicht das gesamte Objekt. (Dies ist, was die ursprüngliche Implementierung in dem Papier auch tut.) Beide Implementierungen sind definitiv schnell genug für den praktischen Gebrauch, wobei die alte, "langsame" Implementierung etwa 100 ms benötigt, um 100000 Werte zu verifizieren und wiederzugeben, und die neue Implementierung unter 10 Frau.

(Vollständige Offenlegung: Ich arbeitete an der neuen Implementierung.)

Die schnelle Implementierung hängt von Haskell-Implementierungsdetails ab. Die ältere, langsamere Implementierung wird automatisch für Haskell-Implementierungen verwendet, mit denen die schnelle Implementierung noch nicht getestet wurde. Bisher haben GHC und Hugs gezeigt, dass sie mit der schnellen Implementierung arbeiten. Sie können die langsame Implementierung mit -fslow anfordern, aber es wird wahrscheinlich nicht aufhören zu arbeiten, wenn GHC seine Implementierung von typeclasses nicht wesentlich überholt. (Auch wenn dies der Fall ist, müssten Sie nur die Pakete neu kompilieren, die Reflektion verwenden, um es wieder funktionsfähig zu machen.)

+0

Ahh süß, so ist 'Data.Reflection' jetzt alles schwarze Magie. :) Gibt es einen Code oder Artikel, die Sie lesen möchten? 'Data.Reflection' macht jetzt schon mehr Sinn, wenn ich das Beispielverzeichnis bemerke. Ich sollte jedoch eine andere Sache auf 'Data.Tagged' und' Data.Proxy' lesen. –