-- | 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
是的,这是家庭作业。所以我正在寻找提示,没有解决方案。我需要一个开始的想法。
答案 0 :(得分:2)
假设您希望testexpression1
和testexpression2
都相同,那么您可以这样继续:
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)相同?你怎么编码呢?