2014-06-26 3 views
11

Mit DataKinds eine Definition wieGibt es einen Grund, warum wir Typen mit DataKinds nicht füllen können?

data KFoo = TFoo 

stellt die Art und den Typ KFoo :: BOXTFoo :: KFoo. Warum kann dann auf Ich gehe

data TFoo = CFoo 

so dass CFoo :: TFoo zu definieren, TFoo :: KFoo, KFoo :: BOX?

Müssen alle Konstruktoren zu einem Typ gehören, der zum Typ * gehört? Wenn ja warum?

Bearbeiten: Ich erhalte keinen Fehler, wenn ich dies tue, weil Konstruktoren und Typen einen Namespace teilen, aber GHC erlaubt Konflikte, da Namen Namen als reguläre Typen, anstatt gefördert Konstruktoren disambiguiert. Die Dokumente sagen, dass ein ' vorangestellt wird, um auf den heraufgestuften Konstruktor zu verweisen. Wenn ich die zweite Zeile ändern, um

data 'TFoo = CFoo 

erhalte ich die Fehler

Malformed Kopf des Typs oder Klassendeklaration: TFoo

+0

Welchen Fehler bekommen Sie, wenn Sie versuchen, 'Daten TFoo' zu definieren? – cdk

Antwort

9

Haben alle Konstrukteure auf einen Typ gehören müssen das gehört zu der Art *?

Ja. Genau das ist * bedeutet: es ist die Art von (gehoben/boxed, ich bin nie sicher über diesen Teil) Haskell Typen. Tatsächlich sind alle anderen Arten nicht wirklich Arten von Typen, obwohl sie die type Syntax teilen. Eher * ist der Metatyp-Level-Typ für Typen und alle anderen Arten sind Metatype-Level-Typen für Dinge, die keine Typen sind, sondern Typkonstruktoren oder etwas völlig anderes.

(Wieder ist es auch etwas über unboxed-Typ Art;. Diejenigen sicherlich Arten sind, aber ich denke, das ist für einen data Konstruktor nicht möglich ist)

+3

Normalerweise würde ich das Wort "type" nicht oft in einem einzigen Beitrag eingeben. – leftaroundabout

+1

'*' ist eine Art von allen aufgehobenen Typen und '#' ist unlifted. '*' und '#' kapseln alle Typen mit Werten zusammen.Boxed bezieht sich nur darauf, ob etwas ein Zeiger ist oder nicht, glaube ich. – user2407038

+2

Boxed, ungepflasterte Typen haben die Art '#', weshalb Sie sie nicht in polymorphen Funktionen verwenden können, die nicht übereinstimmen. Es gibt auch '?', Das ist die Spitze aller Arten und '??', das ist das lub von '*' und '#'. – jozefg

6

alle Konstrukteure zu einem Typ gehören müssen tun, dass gehört zu der Art *? Wenn ja warum?

Der wichtigste Grund, warum sie vom Typ * (oder #) sein muss, ist die Phasentrennung durch GHC eingesetzt: DataKinds während der Kompilierung gelöscht erhalten. Wir können sie nur indirekt Laufzeit darstellen, durch die Definition von Singleton GADT Datentypen:

{-# LANGUAGE DataKinds #-} 

data Nat = Z | S Nat 

data SNat n where 
    SZ :: SNat Z 
    SS :: SNat n -> SNat (S n) 

Aber die DataKind Indizes selbst noch nicht Laufzeit existieren. Die verschiedenen Arten bieten eine einfache Regel für die Phasentrennung, die bei abhängigen Typen nicht so einfach wäre (obwohl dies die Programmierung auf Typenebene möglicherweise erheblich vereinfachen würde).