SML数据类型模式匹配中的变量遮蔽问题咨询
问题解答
是的,你猜的没错——SOME s里的s确实遮蔽了外部的参数s。
在SML的模式匹配规则里,构造器后的变量是用来绑定新的局部变量的,不是用来和外部变量做相等匹配的。也就是说,SOME s这个模式的作用是匹配所有SOME类型的实例,同时把实例里的字符串值绑定到这个新的局部s上,所以这个分支会匹配所有SOME _的情况,后面的_ => false分支就完全多余了,这就是编译器报“match redundant”错误的原因。
你想要的是判断SOME里的值是否等于传入的参数,这种场景不能直接用模式匹配的变量绑定,得在匹配分支里加条件判断。比如把第一个例子改成这样:
fun matchs (target : string) : (string option -> bool) = fn x => case x of SOME s => s = target | NONE => false
这里把参数名改成target避免混淆,在SOME s分支里判断捕获到的s是否等于外部的target,这样就只会匹配值为target的SOME实例。
对应你最初的functor例子,修改后应该是这样:
signature FOO = sig val f : string option -> bool end functor MkFoo (val target : string) :> FOO = struct fun f x = case x of SOME s => s = target | NONE => false end structure NewFoo = MkFoo (val target = "foo") val false = NewFoo.f (SOME "bad")
这样NewFoo.f (SOME "bad")就会返回false,符合预期,而且不会再出现冗余匹配的错误。
补充一句:SML的模式匹配核心是解构数据并绑定变量,不是做值的比较。如果需要基于值的判断,必须在匹配分支里写条件表达式(比如=、<>这类操作符)。
内容的提问来源于stack exchange,提问作者qwr
相关产品推荐
相关产品推荐

