比较Haskell中的表达式

时间:2014-07-02 07:28:08

标签: haskell equality

-- | A very simple data type for expressions.
data Expr = Const Int | Add Expr Expr deriving Show

-- | 'Expression' is an instance of 'Num'. You will get warnings because
--   many required methods are not implemented.
instance Num Expr where
    fromInteger = Const . fromInteger
    (+) = Add

-- | Equality of 'Expr's modulo associativity.
instance Eq Expr where
    (==) = error "Not yet implementd: (==)"


-- | A test expression.
testexpression1 :: Expr
testexpression1 = 3 + (4 + 5)

-- | A test expression.
testexpression2 :: Expr
testexpression2 = (3 + 4) + 5

是的,这是家庭作业。所以我正在寻找提示,没有解决方案。我需要一个开始的想法。

2 个答案:

答案 0 :(得分:2)

假设您希望testexpression1testexpression2都相同,那么您可以这样继续:

toEList :: Expr -> [Int]
toEList e1 = reduce e1 []
  where reduce :: Expr -> [Int] -> [Int]
        reduce (Const x) acc = x:acc
        reduce (Add e1 e2) acc = ??? -- Think about how you will accumulate all
                                     -- the values from `Add` to the `acc`.

此功能会评估Expr[Int]的任何内容。现在尝试从该函数实现实例:

instance Eq Expr where
  (Const x) == (Const y) = ???
  e1 == e2 = ??? -- You have to apply `toElist` function and sort them in both
                 -- `e1` and `e2` cases to test their equality.

答案 1 :(得分:1)

"平等模关联性"意味着您正在寻找以下内容(如果我错了,请纠正我!):

(a + b) + c = a + (b + c)

即。 Add上的分组并不重要,但订单确实如此。考虑一下如何将其直接编码为数据类型。例如,上面的内容将如此表示:

Add (Add (Const a) (Const b)) (Const c) (1)
==
Add (Const a) (Add (Const b) (Const c)) (2)

您可以将这些视为树木:

(1)
        Add
       /   \
      /     \
    Add   Const c
  /     \
Const a Const b

(2)
         Add
       /     \
      /      Add
     /     /    \
Const a  Const b Const c

处理像这样的递归数据类型时,我的典型方法是将它们可视化为树并尝试查看模式。你看到一个模式吗?以什么方式(1)与(2)相同?你怎么编码呢?