In Haskell I have the following data structure
data Circ = IN String
| NOT Circ
| AND Circ Circ
| OR Circ Circ
| XOR Circ Circ
I can pattern match functions on this like so:
size :: Circ -> Int
size (IN _) = 0
..
size (XOR a b) = 1 + (size a) + (size b)
but when I try this with an additional argument:
simulate :: Circ -> [(String, Bool)] -> Bool
simulate (IN a) c = findIn c a
simulate (NOT a) c = not $ simulate a c
simulate (AND a b) c = all (simulate a c) (simulate b c)
simulate (OR a b) c = any (simulate a c) (simulate b c)
simulate (XOR a b) = xor (simulate a c) (simulate b c)
I get the error Equations for ‘simulate’ have different numbers of arguments. How can I write a function that pattern matches a data structure with extra arguments?
I tried rewriting the brackets and couldn't find anything about this online.
I expect it to put the values of the data structure in some of the arguments and receive the next argument alongside it.
Thanks in advance!
This is caused by the missing c
in the last clause:
simulate :: Circ -> [(String, Bool)] -> Bool
simulate (IN a) c = findIn c a
simulate (NOT a) c = not $ simulate a c
simulate (AND a b) c = all (simulate a c) (simulate b c)
simulate (OR a b) c = any (simulate a c) (simulate b c)
simulate (XOR a b) c = xor (simulate a c) (simulate b c)
Another problem is that all :: Foldable t => (a -> Bool) -> t a -> Bool
function [Hackage], and any :: Foldable t => (a -> Bool) -> t a -> Bool
function [Hackage] work with a Foldable
of items, not two parameters; so:
simulate :: Circ -> [(String, Bool)] -> Bool
simulate (IN a) c = findIn c a
simulate (NOT a) c = not $ simulate a c
simulate (AND a b) c = simulate a c && simulate b c
simulate (OR a b) c = simulate a c || simulate b c
simulate (XOR a b) c = simulate a c `xor` simulate b c
But we can probably simplify this by making abstraction of the operator:
data Op1 = Not
data Op2 = And | Or | Xor
data Circ
= IN String
| Op1 Op1 Circ
| Op2 Op2 Circ Circ
and work with:
func1 :: Op1 -> Bool -> Bool
func1 Not = not
func2 :: Op2 -> Bool -> Bool -> Bool
func2 And = (&&)
func2 Or = (||)
func2 Xor = xor
simulate :: Circ -> [(String, Bool)] -> Bool
simulate (IN a) c = findIn c a
simulate (Op1 f a) c = func1 f (simulate a c)
simulate (Op2 f a b) c = func2 f (simulate a c) (simulate b c)