Reputation: 7186
I'm writing a function to simplify a Boolean expression. For example, Nand(A, A) == Not(A)
. I've tried to implement this particular rule using pattern matching, like so:
-- 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')
Upon compiling, I get the error:
Conflicting definitions for `q'
Bound at: boolean.hs:73:21
boolean:73:29
In an equation for `simplify'
I think I understand what's going on, and I've worked around it, but I'd just like to know:
Full disclosure: this is related to homework, but the purpose of the course is not to learn Haskell, and I've solved it my own way anyway.
Upvotes: 12
Views: 4546
Reputation: 62818
The "answer" is that you're not allowed to mention the same variable twice in a pattern. Not in Haskell, anyway. The best way to solve this is the one you appear to have already discovered - use pattern guards to test for equality or inequality.
Upvotes: 1
Reputation: 13677
You could stick to your original style:
-- 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')
Also, I think you should simplify before equality testing and not after:
simplify (Nand q q') = if qs == qs' then Not qs else Nand qs qs' where
qs = simplify q
qs' = simplify q'
Upvotes: 2
Reputation: 7186
The solution I've found is to use guards to check for equality of sub-structures:
simplify (Nand q q')
-- Operands equivalent - simplify!
| q == q' = Not (simplify q)
-- Operands different - recurse.
| otherwise = Nand (simplify q) (simplify q')
Upvotes: 16