Я готовлюсь к экзамену "Введение в функциональное программирование".Это одна из проблем, на которой я застрял:
"Для представления комбинации карт используются следующие типы данных:
data Suit = Hearts | Clubs | Diamonds | Spades
deriving Eq
data Rank = Numeric Int | Jack | Queen | King | Ace
deriving Eq
data Card = NormalCard Rank Suit | Joker
deriving Eq
Определение функции
countAces:: [Card] -> Int
countAces = undefined
где countAces возвращает количество карт в данной руке, которые являются тузами или джокерами. Так, например, если в руке три туза и два джокера, ответ будет пять. "
Итак, яЯ подумал, что напишу так:
countAces:: [Card] -> Int
countAces [] = 0
countAces (c:cs) | c == (NormalCard Ace _) = 1 + countAces (cs)
| c == Joker = 1 + countAces (cs)
| otherwise = countAces (cs)
Но это не скомпилируется, и я понял, что не могу написать c == (NormalCard Ace _).Но если я изменю функцию на:
countAces:: [Card] -> Int
countAces [] = 0
countAces (c : cs) = countCard c + countAces cs
where countCard Joker = 1
countCard (NormalCard Ace _) = 1
countCard _ = 0
Тогда это сработает!Поэтому мой вопрос: почему не работает первая версия?
Это ошибка:
* Found hole: _ :: Suit
* In the second argument of `NormalCard', namely `_'
In the second argument of `(==)', namely `(NormalCard Ace _)'
In the expression: c == (NormalCard Ace _)
* Relevant bindings include
cs :: [Card] (bound at exam.hs:96:14)
c :: Card (bound at exam.hs:96:12)
countAces :: [Card] -> Int (bound at exam.hs:95:1)
Valid substitutions include
Hearts :: Suit (defined at exam.hs:87:13)
Clubs :: Suit (defined at exam.hs:87:22)
Diamonds :: Suit (defined at exam.hs:87:30)
Spades :: Suit (defined at exam.hs:87:41)
undefined :: forall (a :: TYPE r).
GHC.Stack.Types.HasCallStack =>
a
(imported from `Prelude' at exam.hs:1:1
(and originally defined in `GHC.Err'))
Огромное спасибо всем, кто нашел время, чтобы прочитать это.