将预期类型与函数中的实际类型匹配时出错

时间:2013-01-27 15:30:42

标签: haskell

我在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

3 个答案:

答案 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)]

随意编辑此