2014-04-05 11 views
8

Ist eine Variable vom Typ es möglich, die Typklassen der internen Variablen ohne Konditionierung auf den genauen Typ zu nutzen? Nehmen wir zum Beispiel an, ich möchte eine Funktion prettyShow schreiben. Wenn der interne Typ eine Instanz von Show ist, sollten wir diese Instanz verwenden; Andernfalls sollten wir die Instanz der Klasse Dynamic verwenden. In Code, könnte dies wie folgt aussehen:Kombinieren von Data.Dynamic und Typklassen

prettyShow :: Dynamic -> String 
prettyShow x = case fromDynamic x :: (forall a. Show a => Maybe a) of 
    Nothing -> show x 
    Just y -> show y 

Edit: Da es scheint dies direkt nicht getan werden kann, was sind einige gute Abhilfe, die getan werden kann?

+0

Kurz gesagt, nein. Ich würde es lieben, wenn diese Informationen verfügbar wären, aber die Klasseninformationen sind verloren und nur ein Typ-Rep bleibt nach der Kompilierung übrig. –

+1

Aber sicher könnte irgendwo eine große Tabelle im Speicher sein, die jeden Typ mit seinen Klassenwörterbüchern verbindet. –

+2

... aber es ist nicht. –

Antwort

6

Dies kann mit der Implementierung von in der open-typerep Bibliothek (wenn Sie mit generischer Programmierung und viele GHC-Erweiterungen akzeptieren) erfolgen.

{-# LANGUAGE TypeOperators #-} 

import Data.TypeRep 

type Types = BoolType :+: IntType :+: ListType 

x, y :: Dynamic Types 
x = toDyn [False,True] 
y = toDyn [1, 2 :: Int] 

test1 = show x 
test2 = show y 

Die Definition von show ist einfach, und die Bibliothek nutzen können weitere Funktionen über dynamische Werte zu definieren. Im obigen Beispiel habe ich ein geschlossenes Universum verwendet. Mit Datentypen à la Carte-Tricks können Sie aber auch Funktionen für offene Universen definieren. Zum Beispiel ist show selbst offen.

Leistung

A simple benchmark zeigt, dass diese Dynamic 2-3 mal langsamer als Data.Dynamic in base für den kleinen Typ Universum oben verwendet wird. Wenn das Universum auf 30 Typkonstruktoren erhöht wird, ist es etwas mehr als 10 Mal langsamer.

Auto Herleiten für neue Typen

open-typerep unterstützt Universen aus einer kleinen Anzahl von vorgegebenen Darstellungsarten zu machen. Es sollte prinzipiell möglich sein, TemplateHaskell zum automatischen Ableiten von Repräsentationen für neue Typen zu verwenden, aber es wird schwierig sein, die richtigen Instanzen für Witness und PWitness zu generieren, da diese davon abhängen, welche anderen Instanzen verfügbar sind. (Witness wird beispielsweise von der Show Instanz für Dynamic verwendet.)

+0

Was ist der Leistungsunterschied zwischen diesem und Data.Dynamic? Kann Ihre Klasse 'Typable' automatisch für Typen abgeleitet werden, für die ich keine Kontrolle habe? –