Сравнить функции в haskell - PullRequest
0 голосов
/ 29 мая 2019

У меня есть список команд ([Command]), который выглядит как [forward 15, left 20, right 10]. Я хочу добавить forward 15 к [Command] всякий раз, когда вижу команду forward 15. Я использовал elem и ==, чтобы сравнить, является ли элемент forward 15 или нет, но это дает мне ошибку No instance for (Eq Command) arising. Кроме того, в другой функции я хочу добавить [left 15, forward 15, forward 15, right 15, right 15, forward 15, forward 15, left 15] к [Command] всякий раз, когда вижу 4 последовательные команды forward 15. Поэтому мой вопрос заключается в том, как сравнивать функции, потому что forward - это функция, и я не могу сравнить ее, используя elem или ==.

Command определяется как type, а не data, поэтому я не могу использовать deriving Eq.

type Command = Funcs -> (Picture, Funcs)

data Funcs = Funcs {pen :: Bool, angle :: Float, point :: Point, penColor :: Color} deriving (Eq, Show)

forward :: Float -> Command
forward x = ....

Ответы [ 2 ]

8 голосов
/ 29 мая 2019

Я рекомендую создать новый тип данных для команд и интерпретатор в семантическую область Command. Например:

data ReifiedCommand
    = Forward Float
    | Backward Float
    | Left Float
    | Right Float
    deriving (Eq, Ord, Read, Show)

interpret :: ReifiedCommand -> Command
interpret (Forward x) = forward x
interpret (Backward x) = backward x
interpret (Left x) = left x
interpret (Right x) = right x

Теперь вы можете сравнить ReifiedCommand s на равенство и провести любую проверку, необходимую для построения подходящего [ReifiedCommand], а затем, в конце концов, вы можете interpret в [Command] (или Скорее всего, я думаю, даже один Command).

0 голосов
/ 29 мая 2019

В вашем определении data может отсутствовать предложение deriving.

Prelude> data Command = Forward Int | Left Int | Right Int deriving (Eq, Show)
Prelude> Forward 15 == Forward 15
True

Если у вас нет предложения-источника, вы увидите

Нет экземпляраfor (Eq Command), возникающая в результате использования '=='

Кстати, хотя верно, что Forward является функцией (конструктора), вы хотите убедиться, что вы== сравнивает не сами функции (вы не можете сделать это в Haskell), а скорее результат применения функции.Таким образом, вы никогда не сможете сравнить

Forward == Forward

, потому что тип Forward равен Int->Command (функция), но вы можете сравнить

Forward 15 == Forward 15

до тех пор, покакогда вы связываете тип Command с классом типов Eq.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...