2016-09-21 12 views
0

Ich habe einen Typ, der so aussieht, und ich möchte die compare Funktion nur die Größe der Ganzzahl berücksichtigen. Haskell Instanz Ord Schwierigkeiten

data Cell = FromLeft Coordinate Int 
      | FromTop Coordinate Int 
      | FromDiagonal Coordinate Int 
      | Empty Coordinate 
    deriving (Eq, Read, Show) 

Der folgende Code funktioniert, aber ich würde etwas elegantere

instance Ord Cell where 
    compare (FromLeft _ x) (FromLeft _ y) = compare x y 
    compare (FromRight _ x) (FromLeft _ y) = compare x y 
    [...] 
+0

Dies ist keine gute 'Ord'-Instanz, da verschiedene Werte als gleichwertig verglichen werden, auch wenn sie sich im Feld' Coordinate' unterscheiden. Wie soll 'Empty' auch vergleichen? – leftaroundabout

+0

@leftroundabout Ja, du hast mir klar gemacht, dass '' 'Ord''' wirklich nicht das ist, wonach ich suche. Es fühlt sich an wie in Haskell, du verbringst viel Zeit damit, zu versuchen, das Typsystem zu umgehen, nur um zu erkennen, dass du es stattdessen gehört haben solltest. – davorb

+0

Sie könnten einen neuen Typ für Ihre 'Ord' -Instanz definieren, anstatt ihn direkt auf' Cell' zu definieren (ähnlich wie es keine 'Monoid'-Instanz für einen numerischen Typ gibt, sondern separate Instanzen für 'Product' und' Sum') Arten). – chepner

Antwort

4

Sie könnten eine Hilfsfunktion definieren bevorzugen:

extractInt :: Cell -> Int 
extractInt (FromLeft _ x) = x 
extractInt (FromTop _ x) = x 
extractInt (FromDiagonal _ x) = x 
extractInt Empty = ??? 

und dann

instance Ord Cell where 
    compare c1 c2 = compare (extractInt c1) (extractInt c2) 

Aber seien Sie vorsichtig: Die obige Instanz verstößt gegen das Antisymmetriegesetz, das besagt, dass wenn x<=y und y<=x dann x==y. Es ist also nicht wirklich eine Bestellung, sondern eine Vorbestellung.