Не удалось сопоставить синоним типа с Either - PullRequest
0 голосов
/ 19 декабря 2018

Я новичок в изучении 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 голосов
/ 19 декабря 2018

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"
...