为什么这些模式匹配重叠?

J F*_*sch 1 haskell

为什么我的模式匹配do块重叠?

 (q, m) <- newRq
 let m2 = appendMsg "first" key m
     (q4, m4) = case m2 of   
               m -> deleteRec key q m2
               _ -> (q, m2)
Run Code Online (Sandbox Code Playgroud)

这会编译警告

Warning: Pattern match(es) are overlapped
         In a case alternative: _ -> ...
Run Code Online (Sandbox Code Playgroud)

并没有按我的意愿行事.似乎对于(q4,m4)它总是返回

[], fromList []
Run Code Online (Sandbox Code Playgroud)

无视m2和m的值是什么.有没有我不期望的局部变量?

我希望用文字来实现:如果m2和m相等,则(q4,m4)应评估为deleteRec key q m2,否则为(q,m2).

Tik*_*vis 12

case(m)中的第一个模式匹配所有内容并将其分配给m.第二个匹配所有内容并丢弃它(_),但没有任何东西可以匹配,因为m它将获得所有内容.

我认为你的意思是像一个switch语句一样工作,但它实际上是作为一组模式工作,就像一个函数声明.所以你case的东西是这样的:

check m2
  where check m = deleteRec key q m2
        check _ = (q, m2)
Run Code Online (Sandbox Code Playgroud)

在这段代码中,你最好只使用一个if:

if m == m2 then deleteRec key q m2 else (q, m2)
Run Code Online (Sandbox Code Playgroud)

您可能还会考虑以if不同方式缩进语句:

if   m == m2
then deleteRec key q m2
else (q, m2)
Run Code Online (Sandbox Code Playgroud)

也应该工作.

但是,一般来说,您实际上可以在case语句中使用警卫,所以这也可以:

case m2 of
  val | m2 == m   -> deleteRec key q m2
      | otherwise -> (q, m2)
Run Code Online (Sandbox Code Playgroud)

这显然比a更难阅读if,但如果你有更多的分支或需要做一些实际的模式匹配,那就有意义了.

  • 是的,你应该*尽可能使用模式匹配.但是不可能与变量的*值*匹配.模式中的变量只是一个像"_"这样的"洞",它可以带走任何东西; 它然后分配那个名字的任何东西. (3认同)