2016-04-07 8 views
0

erfordern Angenommen ich einen Typ wie dieses:Wie typeclass Instanz in Datendefinition

data Graph vertex = Graph { 
    vertices :: [vertex], 
    edgelist :: [(vertex, [vertex])] 
} 

Aber ich möchte eine typeclass Einschränkung für die Variable vom Typ Vertex haben, ich versuchte, es zu tun, wie es gemacht wird mit typeclass Definitionen:

data (Eq vertex) => Graph vertex = Graph { 
    vertices :: [vertex], 
    edgelist :: [(vertex, [vertex])] 
} 

Aber das erzeugt einen Syntaxfehler Illegal datatype context (use DatatypeContexts). Was ist der richtige Weg, um dies zu erreichen? Oder ist das nicht möglich?

+2

"DatatypeContexts" war ein "Feature" in früheren Versionen von Haskell, das entfernt wurde, weil es nicht das tut, was Sie denken und im Wesentlichen immer ein Fehler ist. Es kann sehr nützlich sein, die Einschränkung wegzulassen, selbst wenn es scheint, dass sie immer benötigt wird. Beispielsweise können Sie Ihren Diagrammtyp zu einem Functor machen, aber nicht, wenn Sie diese Einschränkung hinzugefügt haben. –

Antwort

3

Eine Sache, die Sie tun können, ist GADTs zu verwenden:

{-# language GADTs #-} 
data Graph vertex where 
    Graph :: (Eq vertex) => { vertices :: [vertex], edgelist :: [(vertex, [vertex])] } -> Graph vertex 

dies stellt sicher, dass Sie immer Eq vertex in Umfang haben wird , wenn Sie Muster Match auf dem Graph Konstruktor.

5

Die Haskell-Konvention setzt niemals Beschränkungen für Datentypen. Setzen Sie sie stattdessen auf die Funktionen, die auf den Datentypen arbeiten. Dadurch können Sie die Einschränkungen nur auf die Funktionen anwenden, die sie tatsächlich benötigen.