Ассоциативность программирования в haskell

#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. Спасибо или не торопитесь, я думаю, я, возможно, даже понял, что делать неправильно, поскольку ваш ответ кажется логичным, тесты, которые у меня здесь, не будут выполняться, и, возможно, я все понимаю неправильно