2016-11-21 4 views
12

Die Erweiterung DataKinds fördert "Werte" (d. H. Konstruktoren) in Typen. Zum Beispiel True und False werden verschiedene Arten von Art Bool werden.Art Herabstufung (im Gegensatz zu Art Promotion)

Was ich tun möchte, ist das Gegenteil, d. H. Degradieren Typen in Werte. Eine Funktion mit dieser Signatur wäre schön:

demote :: Proxy (a :: t) -> t 

ich tatsächlich tun, zum Beispiel für Bool:

class DemoteBool (a :: Bool) where 
    demoteBool :: Proxy (a :: Bool) -> Bool 

instance DemoteBool True where 
    demoteBool _ = True 

instance DemoteBool False where 
    demoteBool _ = False 

Allerdings würde ich Instanzen schreiben müssen Sie sich für jede Art ich will degradieren zurück zu seinem Wert. Gibt es einen schöneren Weg, dies zu tun, der nicht so viel Standard beinhaltet?

+1

Der Grund, warum Sie es manuell tun müssen, ist Parteilichkeit. Bei einem Typ-Level "b :: Bool" ist nicht sicher, ob es entweder "True" oder "False" ist. Es könnte ein [festgefahrener Typ] sein (https://typesandkinds.wordpress.com/2015/09/09/what-are-type-families/). Ein Singleton beweist, dass sein Typ nicht feststeckt. Dependent Haskell wird in diesem speziellen Fall ein wenig helfen, denn "True" und "True" werden dasselbe sein, aber es gibt immer noch unvermeidliche Probleme mit der Parteilichkeit. –

+0

@BenjaminHodgson hilft die vorhandene "TypeInType" Hilfe hier überhaupt, oder ist das nicht verwandt? – porges

+0

Es würde Spaß machen, wenn strenge Felder, wenn sie aufgehoben werden, keine steckengebliebenen Typen enthalten könnten, ähnlich wie ein strenges Feld keinen Boden enthalten kann. Ich möchte einfach nur über "a ::! Bool" verfügen und es im Code verwenden :) – porges

Antwort

10

, dass eine der Verwendungen von singletons, insbesondere fromSing:

ghci> :m +Data.Singletons.Prelude 
ghci> :set -XDataKinds 
ghci> fromSing (sing :: Sing 'True) 
True 

Es geht noch viele vorformulierten, aber das Paket hat eine Menge davon bereits definiert und ich glaube, es Template Haskell bietet an lassen Sie Ihre eigenen leichter (und mit weniger Code) generieren.