这是我的代码的简化版本:
data Exp = Var String
test :: Exp -> String -> Bool
test e vIn = case e of
Var vIn -> True
_ -> False
Run Code Online (Sandbox Code Playgroud)
当我运行这个:
test (Var "X") "Y"
Run Code Online (Sandbox Code Playgroud)
我得到True,这很奇怪,因为它需要匹配(Var vIn)和(Var s),s~ = vIn.
任何人都可以解释发生了什么,并建议一种方法来解决它?
Haskell不允许匹配模式中的变量,因为这需要这些变量的类型作为其实例Eq.例如,这不起作用
isEqual :: Int -> Int -> Bool
isEqual a a = True
isEqual _ _ = False
Run Code Online (Sandbox Code Playgroud)
它给出了错误:
Conflicting definitions for `a'
...
In an equation for `isEqual
Run Code Online (Sandbox Code Playgroud)
如果Haskell不允许这样的事情,为什么你的例子编译呢?什么发生在你的代码是,vIn在变量case声明阴影的vIn公式测试中的约束变量.如果使用-Wall标志进行编译,编译器也会向您发出警告:
code.hs:7:18: Warning:
This binding for `vIn' shadows the existing binding
bound at code.hs:6:8
Run Code Online (Sandbox Code Playgroud)
这意味着有两个 vIn变量不相等,只有内部变量可见,因为它会影响外部变量.
要修复代码,您必须明确地将函数参数vIn与案例中匹配的值进行比较:
data Exp = Var String
test :: Exp -> String -> Bool
test e x = case e of
Var vIn -> vIn == x -- Explicitly compare vIn to x
_ -> False
Run Code Online (Sandbox Code Playgroud)
或者只是Var在test等式中使用防护和模式匹配,如果这是一个选项:
data Exp = Var String
test :: Exp -> String -> Bool
test (Var a) vIn
| a == vIn = ... {- Code for the case that vIn == a -}
| otherwise = False
Run Code Online (Sandbox Code Playgroud)