无法将同义词与任何一个匹配

时间:2018-12-19 08:47:48

标签: haskell types pattern-matching either

我是学习Haskell的初学者。但不确定Either在模式匹配中如何工作。

这是我的代码:

type Rank = Either Pip Court
type Pip = Int
type Deck = [Card]
data Card = Joker | Card Suit Rank
data Court = Ace | Jack | Queen | King deriving (Show, Eq, Ord)
data Suit = Hearts | Diamonds | Clubs | Spades deriving (Show, Ord, Eq)

snap :: Card -> Card -> String
snap Joker Joker = "SNAP"
snap (Card s1 r1) (Card s2 r2)
    | r1 == r2 = "SNAP"
snap _ _ = "..."

GHCi告诉我Couldn't match type ‘Court’ with ‘Either Pip Court’,有人可以帮我吗?

1 个答案:

答案 0 :(得分:2)

Either不仅仅是类型的并集;这是一个 tagged 联合,这意味着每个值都必须明确指定发生包装值的类型的哪一侧。这是一个示例,(具有为您的Show类型派生的Card实例):

*Main> Card Hearts Jack

<interactive>:3:13: error:
    • Couldn't match type ‘Court’ with ‘Either Pip Court’
      Expected type: Rank
        Actual type: Court
    • In the second argument of ‘Card’, namely ‘Jack’
      In the expression: Card Hearts Jack
      In an equation for ‘it’: it = Card Hearts Jack

Card需要一个Either Pip Court类型的参数,但是您给了它一个简单的Court值。使用显式包装:

*Main> Card Hearts (Right Jack)
Card Hearts (Right Jack)

创建数字卡也是如此:

*Main> Card Hearts 3

<interactive>:5:13: error:
    • No instance for (Num Rank) arising from the literal ‘3’
    • In the second argument of ‘Card’, namely ‘3’
      In the expression: Card Hearts 3
      In an equation for ‘it’: it = Card Hearts 3
*Main> Card Hearts (Left 3)
Card Hearts (Left 3)

您不需要更改snap的定义,因为Eq已经有一个Either实例,只要两个包装类型本身都具有Eq实例;它认为任何Right值都不等于任何Left值,并且如果包装的值相等,则匹配的RightLeft值相等。

*Main> snap (Card Hearts (Right Jack)) (Card Hearts (Left 3))
"..."
*Main> snap (Card Hearts (Right Jack)) (Card Spades (Right Jack))
"SNAP"