У меня есть список команд ([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 = ....
0
Bhushan Oza 29 Май 2019 в 06:38

2 ответа

Лучший ответ

Я рекомендую создать новый тип данных для команд и интерпретатор в семантическую область 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 с точки зрения равенства и выполнить все необходимые проверки, чтобы построить подходящий [ReifiedCommand], а затем, в конце концов, вы можете interpret добавить их в {{ X3}} (или, скорее, я думаю, даже один Command).

8
Daniel Wagner 29 Май 2019 в 03:54

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

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

Если у вас нет оговорки, вы увидите

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

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

Forward == Forward

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

Forward 15 == Forward 15

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

0
Ray Toal 29 Май 2019 в 03:46
56352773