Есть ли способ сравнить две функции в Haskell?
Моя мысль заключается в том, что ответ отрицательный, поскольку функции не получат класс типа Eq. Однако я пытаюсь написать довольно тривиальную функцию, и это похоже на обычную вещь:
search :: ((Enum a) => a -> a) -> Card -> [Card]
search op x list = if (op == succ && rank x == King) ||
(op == pred && rank x == Ace)
then []
else let c = [ n | n <- list, rank n == op (rank x)]
in if length c == 1
then x : search op (head c) list
else []
Сообщение об ошибке:
No instance for (Eq (Rank -> Rank))
arising from a use of `=='
В основном он либо ищет вверх или вниз список карт, которые ищут совпадение с следующей или предыдущей ранжированной картой от x, создавая список. Принимая функцию "pred" или "succ" в качестве оператора, он работает как вперед, так и назад. Тем не менее, мне нужно проверить, что он не выходит за пределы перечисления, иначе он выдает исключение.
Итак, я ищу способ предотвратить исключение или решить эту проблему!
Любые другие указатели на улучшение кода также будут оценены:)
Спасибо за все замечательные советы, это решение, которое я придумал (взятые бит от каждого ответа действительно!):
EDIT: Правильное решение ниже:
maybeSucc x | x == maxBound = Nothing
| otherwise = Just (succ x)
maybePred x | x == minBound = Nothing
| otherwise = Just (pred x)
-- takes a list of cards which have a rank one op than x
-- only if there is exactly one is it sequential, otherwise end matching
search :: (Rank -> Maybe Rank) -> Rank -> [Card] -> [Card]
search op x list = case filter (\n -> Just (rank n) == op x) list of
[y] -> y : search op (rank y) list
_ -> []
Тест:
*Main> let cards = [Card Ace Heart, Card Two Club, Card Three Spade, Card Five Club, Card Four Diamond]
*Main> search maybeSucc Two cards
[Three of Spades,Four of Diamonds,Five of Clubs]
*Main> search maybePred Three cards
[Two of Clubs,Ace of Hearts]