我在getnumfrmcard(xs)的第一个参数中一直得到一个与实际类型[Card]无法匹配的预期类型卡,并且在函数中直接得到(<)的第二个参数,即getnumfrmcard(xs)(检查看如果一张牌是直的)
enter code here
data Card = Cards (Suit,Face) deriving (Eq)
data Hand= Hands[Card]
straight:: Hand->Bool
straight (Hands [] ) =True
straight (Hands (x:xs) )
| null(xs)==True = True
| getnumfrmcard (x) < getnumfrmcard (xs) =straight (Hands xs)
| otherwise = False
答案 0 :(得分:4)
此错误表示函数getnumfrmcard
需要类型为Card
的参数,但会给出[Card]
(卡片列表)。罪魁祸首是你拥有getnumfrmcard (xs)
的倒数第二行。如果您将列表与(x:xs)
匹配,则x
成为列表的头部(单个元素),xs
成为尾部,这是一个列表。所以在
f [] = []
f (x:xs) = xs
f [1,2,3] -- [2,3]
xs
绑定到[2,3]
。
你可以匹配(Hands (x0:x1:xs))
,但是你需要决定如何处理只有一个参数的列表(我还没想过你真正要做的事情)。
另请注意:您通常不需要在Haskell中围绕函数参数使用括号,因此您需要编写getnumfrmcard (xs)
而不是getnumfrmcard xs
。
答案 1 :(得分:1)
另外,如果你想检查你是否有直线,仅检查每张卡是否低于下一张卡是不够的,它必须一个更低。
我想到了一个更多的Haskell-y解决方案:
straight (Hands cards) = and $ zipWith nextStraight cards (tail cards)
where nextStraight c c' = getnumfrmcard c' == getnumfrmcard c+1
zipWith nextStraight cards (tail cards)
将cards
中的每对相邻元素组合为函数nextStraight
(检查两张卡是否具有相邻值的函数)。然后我们通过要求所有对必须验证谓词(因此and
函数)来组合结果布尔列表。
当然,必须事先对手进行分类才能使此方法有效,否则某些直道将无法被检测到(例如[2H,3D,5S,4D,6C])。
答案 2 :(得分:0)
haskell中的编码并不是那么明显,我会在你的问题中添加更多代码,这样你就不会有更多问题:)所以基于Paul回答的答案可能看起来像我想的那样。
module Test where
data Card = Cards (Int, Int) deriving (Eq, Ord)
data Hand = Hands [Card]
straight :: Hand -> Bool
straight (Hands [] ) = True
straight (Hands [x0] ) = True
straight (Hands (x0:x1:xs) )
| null(xs) == True = True
| x0 < x1 = straight (Hands xs)
| otherwise = False
main :: IO ()
main = print $ straight $ Hands [Cards (5,1), Cards(4,4)]
随意编辑此