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