为什么我的模式在do块重叠内匹配?
(q, m) <- newRq
let m2 = appendMsg "first" key m
(q4, m4) = case m2 of
m -> deleteRec key q m2
_ -> (q, m2)
这会编译警告
Warning: Pattern match(es) are overlapped
In a case alternative: _ -> ...
并且不能按我的意愿行事。似乎对于(q4,m4)它总是返回
[], fromList []
忽略m2和m的值。是否存在我不期望的局部变量?
我希望用词来实现:如果m2和m相等,则(q4,m4)应评估为deleteRec key q m2
,否则评估为(q,m2)。
答案 0 :(得分:12)
case
(m
)中的第一个模式匹配所有内容并将其分配给m
。第二个匹配所有内容并将其丢弃(_
),但没有任何内容可供匹配,因为m
将获得所有内容。
我认为你的意思是像switch
语句一样工作,但它实际上是作为一组模式工作,就像一个函数声明。因此,您的case
与以下内容相同:
check m2
where check m = deleteRec key q m2
check _ = (q, m2)
在此代码中,您最好只使用if
:
if m == m2 then deleteRec key q m2 else (q, m2)
您也可以考虑以不同方式缩进if
语句:
if m == m2
then deleteRec key q m2
else (q, m2)
也应该有用。
但是,一般情况下,您实际上可以在case
语句中使用警卫,所以这也可以使用:
case m2 of
val | m2 == m -> deleteRec key q m2
| otherwise -> (q, m2)
这显然比if
更难阅读,但如果你有更多的分支或需要做一些实际的模式匹配,那就没有意义。