比较Haskell中的表达式

比较Haskell中的表达式,haskell,equality,Haskell,Equality,是的,这是家庭作业。所以我在寻找线索,没有解决办法。我需要一个开始的想法 假设您希望testexpression1和testexpression2都相等,那么您可以这样进行: -- | 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 warning

是的,这是家庭作业。所以我在寻找线索,没有解决办法。我需要一个开始的想法

假设您希望
testexpression1
testexpression2
都相等,那么您可以这样进行:

-- | 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
此函数将计算任何
Expr
[Int]
。现在尝试从该函数实现实例:

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`.
“相等模结合性”意味着您正在寻找以下内容(如果我错了,请纠正我!):

i、 e.
Add
上的分组不重要,但顺序重要。考虑如何将其直接编码到数据类型中。例如,上述内容可以这样表示:

(a + b) + c = a + (b + c)
您可以将这些可视化为树:

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

我处理此类递归数据类型的典型方法是将它们可视化为树,并尝试查看模式。你看到模式了吗?(1)与(2)在哪些方面相同?如何对其进行编码?

是否应
testexpression1
等于
testexpression2
?如果是的话,你可能想对它们进行评估并比较结果。顺便说一句:提示很难包含在答案中——也许你应该把它贴在reddit上?是的,它们应该是相等的。好吧,也许你是对的。对不起:如果它是模关联性,你可能想考虑使用一个在关联性下不变的表示,或者转换成这样的表示来进行比较。考虑一个表达式列表,例如,如果你只看结果(“代码>12=12</CODE>当然”),则暗示关联性——因此,对表达式进行评估,并使用<代码> INT/COS> S代码> EQ INSTANCENO。您不希望
2+3
等于
4+1
。不管你怎么说,这不是“等式模结合性”。@n.m.谢谢,我误解了这个问题。在代码中的哪个位置我必须做某事?根据你的问题:我认为他们都有相同的“深度”,相同的起点,并且在某种程度上反映了他们。。我不确定,如果我得到它。我对这种由老师实现的新数据类型有很大的问题:\@福曼试图将(a+b)+(c+d)和a+(b+(c+d))的树形象化;它们也是等价的模结合性,但深度不同!另外,试着想想你可能会在树上执行什么样的常见操作,你可能会看到一个解决方案正在形成。我可以想象得到。我想它们在叶子上是一样的。从左到右,树叶上写着“a b c d”。从这个逻辑观点来看,这没有问题。我对Haskell中的编解码器有问题。我不知道如何用这个短语来表达:\@福曼,为什么不试着把叶子收集到其他容器里,看看顺序是否相同?你理解其中的逻辑,这是战斗的90%。感谢你的大力支持和激励!:)你能告诉我火车的左边吗?右边有我能匹配的图案吗?如何检查输入是一个叶子还是另一个“添加”?
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