Haskell does not allow matching variables in templates, because for these types of types these variables must be an Eq instance. For example, this does not work.
isEqual :: Int -> Int -> Bool isEqual aa = True isEqual _ _ = False
It gives an error:
Conflicting definitions for `a' ... In an equation for `isEqual
If Haskell doesn't allow such things, why does your example compile? What happens in your code is that the vIn variable in the case expression shades the vIn variable associated in the equation for the test. The compiler also warns about this if you compile the -Wall flag:
code.hs:7:18: Warning: This binding for `vIn' shadows the existing binding bound at code.hs:6:8
This means that there are two vIn variables that are not equal, only the inside is visible because it obscures the outside.
To fix the code, you will have to explicitly compare the function argument with the vIn value, which is appropriate in the case:
data Exp = Var String test :: Exp -> String -> Bool test ex = case e of Var vIn -> vIn == x -- Explicitly compare vIn to x _ -> False
Or just use protection and pattern matching on Var in the test equation if this is an option:
data Exp = Var String test :: Exp -> String -> Bool test (Var a) vIn | a == vIn = ... {- Code for the case that vIn == a -} | otherwise = False
source share