0

我一直在 getnumfrmcard (xs) 的第一个参数和 (<) 的第二个参数即 getnumfrmcard(xs) 函数中得到一个无法匹配预期类型 Card 和实际类型 [Card]牌是顺子)

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
4

3 回答 3

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.

于 2013-01-27T15:47:31.563 回答
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])。

于 2013-01-28T12:37:31.097 回答
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)]

随意编辑这个

于 2013-01-27T17:30:49.497 回答