【问题标题】:Couldn't match type Synonym with Either无法将类型同义词与 Either 匹配
【发布时间】:2019-05-19 17:26:00
【问题描述】:

我是学习 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’,有人可以帮我吗?

【问题讨论】:

  • 无法复制。该代码在我系统上的 GHCi 中加载良好。
  • 你在 GHCi 中尝试了什么?
  • GHC 抱怨脚本的哪一部分?,发布完整的错误
  • 听起来您正在尝试使用Card Hearts Jack 而不是Card Hearts (Right Jack) 之类的内容创建卡片。 (同样,Card Hearts (Left 3)。)
  • @chepner 我想我误解了与数据类型不匹配的任何一个的含义,尤其是当类型在这种语言中如此重要时:)

标签: haskell types pattern-matching either


【解决方案1】:

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

*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 的定义,因为Either 已经有一个Eq 实例,只要两个包装类型本身都有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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 2020-02-19
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多