Here's (a simplified version of) my code:
data Exp = Var String
test :: Exp -> String -> Bool
test e vIn = case e of
Var vIn -> True
_ -> False
When I run this:
test (Var "X") "Y"
I get True, which is odd because it requires matching (Var vIn) and (Var s), s ~= vIn.
Can anyone explain what's going on, and suggest a way to fix it?
Haskell doesn't allow to match variables in patterns, because that would require the types of these variables to be an instance of Eq
. For example, this doesn't work
isEqual :: Int -> Int -> Bool
isEqual a a = True
isEqual _ _ = False
It gives the error:
Conflicting definitions for `a'
...
In an equation for `isEqual
If Haskell doesn't allow such things, why does your example compile then? What happens in your code is that the vIn
variable in the case
statement shadows the vIn
variable bound in the equation for test. The compiler also warns you about this if you compile with 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, which are not equal, Only the inner one is visible, because it shadows the outer one.
To fix the code, you'll have to explictly compare the function argument to the vIn
value matched in the case:
data Exp = Var String
test :: Exp -> String -> Bool
test e x = case e of
Var vIn -> vIn == x -- Explicitly compare vIn to x
_ -> False
Or just use guards and pattern match on Var
in the test
equation if that's 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
The vIn
in your match is shadowing the vIn
function argument, and the binding always succeeds. You can bind to a new variable and use a pattern guard to check the values are equal:
test e vIn = case e of
Var v | v == vIn -> True
_ -> False
alternatively you can match against Var
directly instead of using case
:
test (Var v) vIn = v == vInt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With