Die Frage ist hier eine Verwechslung zwischen dem Konzept eines Typkonstruktor und einem Daten Konstruktor. Der Kürze halber werde ich den Unterschied anhand eines Beispiels veranschaulichen.
data Foo a = Bar [a]
In dem obigen Ausdruck, Foo
ist der Typkonstruktor und Bar
ist die Daten Konstruktor. Der Hauptunterschied besteht darin, dass Foo
ein Wert in Haskell type space ist und Bar
ein Wert in seinem Datenbereich ist. Ein Wert im Typraum kann nicht im Datenraum verwendet werden und umgekehrt. Zum Beispiel würde der Compiler bei den folgenden Ausdrücken einen Fehler haben.
someVariable :: Bar Int
someVariable = Foo [15]
Der nächste Ausdruck ist jedoch vollständig gültig.
someVariable :: Foo Int
someVariable = Bar [15]
Zusätzlich werden alle Typkonstruktoren muss mit einem Großbuchstaben beginnen. Alle Typen, die mit einem Kleinbuchstaben beginnen, werden als Typvariablen betrachtet, nicht als Typkonstruktoren (die a
in unserer obigen Definition ist ein Beispiel dafür).
Die Einführung von Smart Konstruktoren für dieses Problem eine weitere Ebene, aber der Schlüssel ist zu verstehen, dass Smart Konstrukteure Daten Konstrukteure sind, Konstrukteure nicht geben. In Ihrer Definition von Rec
versuchten Sie Ihr Mobil Konstruktor zu verwenden, domain
, in der Typdeklaration für dint
Feld. Da jedoch domain
ein Daten Konstruktor kein Typkonstruktor ist, und es ist niedriger Fall versuchte der Haskell Compiler domain
als Name eines Typs Variable zu interpretieren. Da Sie in Ihrer Definition des Typs Rec
nie eine Variable mit dem Namen domain
angegeben haben, hat der Compiler einen Fehler ausgelöst.
Sie nicht wirklich benötigen die Daten Konstruktor für Domain
zu exportieren, das Problem zu lösen, sondern nur die Art selbst. Dies kann folgendermaßen erreicht werden.
module Domain (
Domain(), domain,
...
) where
Einschließlich Domain()
in der Exportdefinition sagt Haskell den Domain
Typkonstruktor, aber keine seiner Daten Konstrukteuren zu exportieren. Dies bewahrt die Sicherheit, die Sie mit dem sicheren Konstruktor haben wollten, und erlaubt es Ihnen, Typen korrekt zu definieren. Sie können Ihren neu exportierten Typ jetzt in Ihrer Definition Rec
verwenden.
import Domain (Domain(), domain)
data Rec = Rec
{ dint :: Domain Int
...
}
Weitere Informationen ich Ihnen dringend empfehlen, die HaskellWiki Artikel auf constructors und smart constructors lesen.
Bitte geben Sie Ihren Code ein. Es ist sehr schwierig zu sagen, was hier vor sich geht. – Kwarrtz
Es hört sich so an, als würden Sie Typen und Typenkonstruktoren wahrscheinlich durcheinander bringen. Ich kann jedoch nicht sagen, was Sie gepostet haben. – Kwarrtz
@Kwarrtz Code hinzugefügt. –