Daniel Buckmaster
Daniel Buckmaster

Reputation: 7186

Implying equality in a Haskell pattern match

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:

  1. Why is this sort of pattern matching not possible?
  2. Is there an idiomatic workaround?

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

Answers (3)

MathematicalOrchid
MathematicalOrchid

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

nponeccop
nponeccop

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

Daniel Buckmaster
Daniel Buckmaster

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

Related Questions