无法将预期类型`Bool'与实际类型`Card - >匹配布尔”

时间:2011-11-13 08:58:40

标签: haskell

有我的代码:

data Suit = Spade | Heart | Diamond | Club deriving (Eq, Show)
data CVal = Ace | King | Queen | Jack | Ten | Nine | Eight | Seven | Six | Five | Four | Three | Two deriving Show
data Card = Card Suit CVal deriving Show

sameSuit :: Card -> Card -> Bool
sameSuit (Card Spade _) (Card Spade _)     = True
sameSuit (Card Heart _) (Card Heart _)     = True
sameSuit (Card Diamond _) (Card Diamond _) = True
sameSuit (Card Club _) (Card Club _)       = True
sameSuit (Card x _) (Card y _)             = False

getNumber :: Card -> Int
getNumber (Card _ Two)   = 2
getNumber (Card _ Three) = 3
getNumber (Card _ Four)  = 4
getNumber (Card _ Five)  = 5
getNumber (Card _ Six)   = 6
getNumber (Card _ Seven) = 7
getNumber (Card _ Eight) = 8
getNumber (Card _ Nine)  = 9
getNumber (Card _ Ten)   = 10
getNumber (Card _ Jack)  = 11
getNumber (Card _ Queen) = 12
getNumber (Card _ King)  = 13
getNumber (Card _ Ace)   = 14

beats :: Card -> Card -> Bool
beats x y = if sameSuit (x y) && getNumber(x) > getNumber(y) then True else False

错误讯息:

Couldn't match expected type `Bool' with actual type `Card -> Bool'
In the return type of a call of `sameSuit'
In the first argument of `(&&)', namely `sameSuit (x y)'
In the expression: sameSuit (x y) && getNumber (x) > getNumber (y)

我不明白为什么我不能在“节拍”中调用功能“sameSuit”。如果我从前奏中称呼它,例如前奏> sameSuit(Card Club 10)(Card Club Ace)它返回正确的值和功能类型是Bool,而不是“Card - > Bool”。我做错了什么?有人可以向我解释一下吗?

2 个答案:

答案 0 :(得分:3)

beats中,您似乎尝试使用类似C的语法将多个函数称为function(args)。 Haskell不使用这种语法;函数应用程序由简单的标记邻接编写,只有嵌套表达式才需要括号。

getNumber(x)无害,但毫无意义。它被解析为函数getNumber到括号表达式(x)的应用,当然它只相当于getNumber x,所以它可以做你想要的。

sameSuit (x y)被解析为函数sameSuit对单个参数的应用,括号表达式(x y)。子表达式反过来将函数x应用于y,在此上下文中没有任何意义,因为xCard,而不是函数。您需要为sameSuit提供两个参数,如sameSuit x y

由于sameSuit的类型为Card -> Card -> Bool,因此仅提供一个参数的sameSuit类型为Card -> Bool。这是编译器向您报告的错误;你显然不能&&一个函数和一个Bool

如果编译器以不同的顺序检查事物,它也会告诉您x y不是Card类型,而x不是函数。

答案 1 :(得分:1)

beats的更正实施是:

beats x y = (sameSuit x y) && (getNumber x > getNumber y)

因此,您可以sameSuit中呼叫beats,但您必须使用parens。

编辑:实际上,您不需要parens。在您的代码中,您调用了sameSuit (x y),但是您必须在没有代码的情况下调用它:sameSuit x y