确定卡是否是某种诉讼

时间:2017-06-01 23:03:53

标签: haskell

data Card = Card CardValue Suit deriving (Eq)

如果我有一张卡片,我想确定这张卡片是哪种套装

我曾尝试使用警卫,但我仍然不确定如何正确使用它们。如果我要编写那种我想要做的事情的伪代码,那就是

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

这就是我做了多少,就像我说我试图使用警卫一样,但我收到错误“输入错误解析'|'当我使用以下代码时

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

我做错了什么?逻辑很简单,我只是不熟悉haskell的语法

3 个答案:

答案 0 :(得分:4)

您正在寻找case表达式(有时在其他语言中称为match):

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"

其中_模式匹配所有不匹配的输入 - IIRC案例表达式要求所有模式匹配或者它都会出错,但请检查我。

请注意,这也适用于字符串文字作为大小写匹配模式:

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

当然,如果您不打算仅针对这两种情况进行测试,那么您只需直接退回诉讼:

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

:)

Reference

答案 1 :(得分:3)

问题是你写了

suitOf (Card _ s) = s

您不会在函数的第一行写入等号,只能在每个后卫之后。如果您将该行更改为

suitOf (Card _ s)

它应该有用。此外,这仅适用于Suit是[Char]的类型同义词(我认为它是,但只是要检查的内容)。

答案 2 :(得分:3)

我不确定为什么会出现无效的情况,但只有三种可能性,我只会为每种情况编写单独的方程式。

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

没有错误的情况,当然只是

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

并且使用记录语法,您甚至不需要自己定义函数:

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