2013-05-03 6 views
8

Gibt es in Haskell eine Möglichkeit, einen Datentyp durch den Wert seiner Komponenten zu begrenzen? Ich habe ein Beispiel entworfen. Angenommen, Sie haben ein Dame Spiel. Ein Prüfer ist entweder vom Typ Schwarz oder Weiß.Können Haskell-Datendeklarationen durch Typwerte begrenzt werden?

data CheckerType = BlackChecker | WhiteChecker deriving (Eq) 

data Checker = Checker CheckerType Int 

Das Spielbrett für ein Schachspiel enthält eine Reihe von schwarzen Dame und weißen Dame. zu sein, von CheckerType schwarz, und die zweiter zu dem gegenüberliegenden Typ

data GameBoard = GameBoard ([Checker]) ([Checker]) 

In der vorherige Erklärung gibt es eine Möglichkeit, die Kontrolleure in den ersten [Checker] zu erzwingen?

+0

mögliche Duplikate von [Positive Ganzzahl] (http://stackoverflow.com/questions/11910143/positive-integer-type) – dave4420

Antwort

13

Der einfachste Weg, um etwas Ähnliches zu tun ist, um die Checker Typ mit parametrieren, was ein „Phantom-Typ“ genannt wird:

data Black 
data White 

Beachten Sie, dass keine dieser keine Werte haben. Sie existieren nur, um anzuzeigen, welche Farbe ein Checker ist.

data Checker a = Checker Int 

data GameBoard = GameBoard [Checker Black] [Checker White] 

By the way, brauchen Sie nicht, diese Klammern in der GameBoard Erklärung.

Der Nachteil dieses Ansatzes besteht darin, dass die zwei Farben jetzt verschiedene Typen sind, was bedeutet, dass Sie keine Funktion schreiben können, die beispielsweise eine Liste von Karos mit mehreren Farben und nur eine Farbe enthält.

Sie könnten die Phantom-Typen ein bisschen konkreter machen, um erlaubt Farben zu verfolgen:

data Black = Black 
data White = White 

data Checker a = Checker a Int 

type AnyChecker = Checker (Either Black White) 

Aber das eine Menge Ärger kann schnell zu bedienen.

Was ich vermute, dass Sie wirklich wollen, ist eine Möglichkeit, den Bereich der zulässigen Werte in einem Kontext zu beschränken, ohne es in allen Kontexten zu einem komplett anderen Typ zu machen. Leider ist das in Haskell nicht wirklich einfach möglich.

Es ist eine vernünftige Idee, und einige Sprachen haben ähnliche Eigenschaften. Solche Unterscheidungen auf verallgemeinerte Art zu unterstützen, ist nicht einfach, Haskells existierendes Typsystem ohne Kollateralschaden zu ergänzen, obwohl beispielsweise die Typinferenz weniger robust ist, sogar in einem Code, der eine solche Eigenschaft nicht verwendet.

+7

Wenn Sie das nicht möchten, könnte eine Problemumgehung mit Ihrem ursprünglichen Code bleiben , aber exportieren Sie nicht den 'GameBoard'-Konstruktor. Fordern Sie stattdessen die Benutzer Ihres Moduls auf, einen benutzerdefinierten Konstruktor aufzurufen, der die Prüfer entsprechend zuweist und sie mithilfe von Funktionen aktualisiert, die die Farbzuordnungen beibehalten. – mhwombat

Verwandte Themen