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的语法
答案 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
:)
答案 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)