11

我正在编写一个函数来简化布尔表达式。例如,Nand(A, A) == Not(A)。我尝试使用模式匹配来实现这个特定的规则,如下所示:

-- Operands equivalent - simplify!
simplify (Nand q q) = Not (simplify q)
-- Operands must be different, so recurse.
simplify (Nand q q') = Nand (simplify q) (simplify q')

编译后,我收到错误:

Conflicting definitions for `q'
Bound at: boolean.hs:73:21
          boolean:73:29
In an equation for `simplify'

我想我了解发生了什么,并且我已经解决了它,但我只想知道:

  1. 为什么这种模式匹配不可能?
  2. 有惯用的解决方法吗?

完全披露:这与家庭作业有关,但课程的目的不是学习 Haskell,反正我已经用自己的方式解决了。

4

3 回答 3

15

我找到的解决方案是使用警卫来检查子结构的相等性:

simplify (Nand q q')
    -- Operands equivalent - simplify!
    | q == q' = Not (simplify q)
    -- Operands different - recurse.
    | otherwise = Nand (simplify q) (simplify q')
于 2012-08-23T04:08:11.643 回答
2

你可以坚持你原来的风格:

-- Operands equivalent - simplify!
simplify (Nand q q') | q == q' = Not (simplify q)
-- Operands must be different, so recurse.
simplify (Nand q q') = Nand (simplify q) (simplify q')

另外,我认为你应该在平等测试之前而不是之后简化:

simplify (Nand q q') = if qs == qs' then Not qs else Nand qs qs' where
    qs = simplify q
    qs' = simplify q'
于 2012-08-29T21:38:05.333 回答
1

“答案”是不允许在一个模式中两次提及同一个变量。无论如何,不​​在 Haskell 中。解决此问题的最佳方法是您似乎已经发现的方法 - 使用模式保护来测试相等或不相等。

于 2012-08-23T10:20:06.820 回答