#haskell #equality #instances
#haskell #равенство #экземпляры
Вопрос:
Итак, это мое задание здесь, в котором я должен запрограммировать ассоциативность некоторых выражений, я работал над этим несколько часов, и я просто упускаю что-то очевидное. Вот мои последние две идеи, которые оба работают, но не могут правильно оценивать действительно равные выражения (первая выдает ошибку синтаксического анализа) Я не могу понять, что не так. Справка: (
data Expr = Const Int | Add Expr Expr deriving Show
instance Num Expr where
fromInteger = Const . fromInteger
( ) = Add
-- I have to write here
instance Eq Expr where
(Const i) == (Const j) = i == j
(Add i j) == (Add a b) = i == a amp;amp; j == b || i ==b amp;amp; j == a
(==) (Add e3 (Add e1 e2)) (Add (Add e4 e5) e6) =
(Add(Add e1 e2) e3)==(Add e1 (Add e2 e3))
_ == _ = False
Комментарии:
1. Можете ли вы показать ошибку синтаксического анализа?
2. Ошибка синтаксического анализа в шаблоне y z
3. @Fatalgoddess Проблема в том, что вы не можете создать шаблон с
помощью, поскольку шаблоны могут быть сформированы только из конструкторов данных, переменных и литералов.
это функция, компилятор не обладает специальными знаниями о ней, чтобы понять, что
x y
означает шаблон.4. Не могу понять, как сделать это по-другому.. (Const i) == (Const j) = i == j (добавить e1 e2) == (Добавить e3 e4) = e1 == e3 amp;amp; e2 == e4 _ == _ = False также выдает ошибки
5. ваша вторая идея выглядит так, как будто она на правильном пути. Но вы должны переместить шаблон catch-all
_ == _
в низ, прямо сейчас это предотвратит рассмотрение любых других совпадений
Ответ №1:
Возможно, вы захотите заменить:
(==) (Add e3 (Add e1 e2)) (Add (Add e4 e5) e6) = (Add(Add e1 e2) e3)==(Add e1 (Add e2 e3))
Автор:
(==) (Add e1 (Add e2 e3)) e = (Add(Add e1 e2) e3) == e
(==) e (Add e1 (Add e2 e3)) = e == (Add(Add e1 e2) e3)
Каждое уравнение просто перебалансирует одно дерево выражений для получения левой рекурсии, не пытаясь проверить, действительно ли выражения равны, поэтому вам нужно третье уравнение:
(==) (Add e1 e2 ) (Add e3 e4) = (e1 == e3) amp;amp; (e2 == e4)
Затем я определяю функцию, которая явно принимает Expr
в качестве параметров для тестирования (==)
:
testexpr :: Expr -> Expr -> Bool
testexpr a b = a == b
и testexpr (1 (2 3)) ((1 2) 3)
дает True
результат .
Поскольку это назначение, интеграция этого изменения в ваш код и его реорганизация, чтобы заставить его работать, остаются в качестве упражнения.
Комментарии:
1. Спасибо или не торопитесь, я думаю, я, возможно, даже понял, что делать неправильно, поскольку ваш ответ кажется логичным, тесты, которые у меня здесь, не будут выполняться, и, возможно, я все понимаю неправильно