2015-10-12 4 views
8

A recent question führte mich wie zu fragen, einWie kann ich Polymorphismus in eine Datenstruktur pushen?

forall f . Functor f => [LensLike f s t a b] 

in ein mit !!,

[ReifiedLens s t a b] 

Es gibt einen einfachen Weg, um es wirklich langsam durch die Indizierung in die Liste zu tun, um zu konvertieren, aber es ist ziemlich unglaublich ineffizient. Es fühlt sich so an, als ob es genug Parameter geben sollte, um einen ähnlichen Trick auszuführen wie in reflection, aber ich kann nichts herausfinden. Ist es überhaupt möglich, dies effizient zu tun?

+2

Ich glaube nicht, dass das überhaupt möglich ist. Wir müssten (operativ) von 'Functor f -> [LensLike fs t a b]' zu '[Functor f -> LensLike fs t a b]' gehen. Wir müssen einen 'Functor f' übergeben, um zunächst eine Liste zu erstellen, und es gibt keine. –

+2

@ AndrásKovács Vielleicht können wir ein parametrisches Argument verwenden, um uns davon zu überzeugen, dass Funktionen vom Typ 'Functor f -> [LensLike f s t a b]' die Länge ihrer Ergebnisliste wählen müssen, ohne das 'Functor f'-Argument in sinnvoller Weise zu untersuchen. Dann ist es einfach, den Rest des Weges von dort zu bekommen. (Natürlich trifft diese Behauptung natürlich nicht auf Funktionen des Typs 'Functor F -> [LensLike F s t a b]' für ein bestimmtes 'F' zu.) –

+0

@ AndrásKovacs, das war meine Angst. Wir brauchten eine Art "Superfactor" -Wörterbuch, das wir weitergeben konnten und das magisch in der Lage sein würde, die Identität eines anderen 'Functor'-Wörterbuchs anzunehmen. – dfeuer

Antwort

5

Testing aus meiner Idee in den Kommentaren, können Sie in der Tat dies, indem sie durch ALens direkt schreiben:

convert :: (forall f. Functor f => [LensLike f s t a b]) -> [ReifiedLens s t a b] 
convert ls = [Lens (cloneLens l) | l <- ls] 

ALens basiert auf dem Pretext Funktors:

type ALens s t a b = LensLike (Pretext (->) a b) s t a b 

newtype Pretext p a b t = Pretext { runPretext :: forall f. Functor f => p a (f b) -> f t } 

Dies ermöglicht eine Verwendung einzeln Functor, um alle von ihnen darzustellen, zumindest für den Objektivgebrauch.

Ich frage mich immer noch, ob es eine Methode gibt, die allgemein und nicht nur für Objektive funktioniert.

+0

Ich finde immer noch "Vorwand" verwirrend. Wenn man es auf "(->)" anwendet, kann ich es als eine teilweise angewandte Linse betrachten, aber seine Nützlichkeit und Allgemeinheit verwirrt mich immer noch. – dfeuer

Verwandte Themen