Не удалось сопоставить синоним типа с 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 ответ

Решение

Either это не просто союз типов; это теговое объединение, что означает, что каждое значение должно явно указывать, на какой "стороне" типа встречается переносимое значение. Вот пример, (с 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 значение и соответствие Right или же Left значения равны, если обернутые значения равны.

*Main> snap (Card Hearts (Right Jack)) (Card Hearts (Left 3))
"..."
*Main> snap (Card Hearts (Right Jack)) (Card Spades (Right Jack))
"SNAP"
Другие вопросы по тегам