2017-06-01 1 views
1
data Card = Card CardValue Suit deriving (Eq) 

Wenn ich eine Karte Ich bestimmen will gegeben habe, die Klage ist diese KarteBestimmung, ob eine Karte ein bestimmte Anzug ist

ich versucht habe, Wachen, aber ich bin immer noch nicht sicher, wie man verwenden sie richtig. Wenn ich Pseudo-Code der Art der Sache zu schreiben, war ich versuche, es zu tun entlang der Linien wäre

if s == D 
    then D 
else if s == D 
    then D 

Dies ist, wie viel ich getan habe, wie ich sagte, ich versuche, Wachen zu verwenden, aber Ich habe einen Fehler "parse error on input '|' wenn ich den folgenden Code verwendet

suitOf :: Card -> Suit 
suitOf (Card _ s) = s 
    | s == D = D 
    | s == S = S 
    | otherwise = error "Invalid" 

Was ist es, dass ich falsch mache? Die Logik ist ziemlich einfach, ich bin mit der Syntax von Haskell einfach nicht vertraut noch

Antwort

3

Das Problem ist, dass Sie

schrieb
suitOf (Card _ s) = s 

Sie schreiben nicht die Gleichen auf der ersten Zeile der Funktion unterschreiben, nur nach jeder Wache. Wenn Sie diese Zeile

ändern
suitOf (Card _ s) 

sollte es funktionieren. Außerdem funktioniert das nur, wenn Suit ein Typensynonym für [Char] ist (was ich annehme, aber nur etwas zu überprüfen).

4

Sie sind für den case Ausdruck suchen (manchmal match in anderen Sprachen):

data Suit = Diamond | Spade | Club | Heart deriving (Eq, Ord) 
data Card = Card CardValue Suit deriving (Eq) 

suitOf :: Card -> Suit 
suitOf (Card _ s) = 
    case s of 
    Diamond -> Diamond 
    Spade -> Spade 
    _ -> error "Invalid" 

wo das _ Muster passt alle nicht akzeptierten Eingabe - IIRC Fall Ausdrücke erfordern alle Muster abgestimmt oder werden Es wird ein Fehler, aber überprüfe mich darauf.

Beachten Sie, dass diese mit Stringliterale wie es der Fall Match Muster funktioniert auch:

toSuit :: String -> Suit 
toSuit s = 
    case s of 
    "Diamond" -> Diamond 
    "Spade" -> Spade 
    _ -> error "Invalid" 

Natürlich, wenn Sie nicht nur für diese beiden Fälle testen, würden Sie nur den Anzug zurückkehren würde direkt:

suitOf :: Card -> Suit 
suitOf (Card _ s) = s 

:)

Reference

3

I‘ Ich bin mir nicht sicher, warum es einen ungültigen Fall geben würde, aber für nur drei Möglichkeiten würde ich nur getrennte Gleichungen für jeden schreiben.

suitOf :: Card -> Suit 
suitOf (Card _ D) = D 
suitOf (Card _ S) = S 
suitOf (Card _ _) = error "Invalid" 

Ohne Fehlerfall ist es natürlich nur

suitOf :: Card -> Suit 
suitOf (Card _ s) = s 

und mit Rekord-Syntax Sie brauchen nicht einmal die Funktion selbst zu definieren:

data Card = Card { rankOf :: CardValue, suitOf :: Suit } deriving (Eq) 
Verwandte Themen