我在Haskell中的以下函数存在问题,该函数仅压缩元素" B"在列表中:
data El = A | B deriving (Show)
zS :: [El] -> [El]
zS [] = []
zS (A:xs) = A : zS xs
zS (B:xs) = B : zS xs
zS (B:B:xs) = B : zS xs
zS (B:A:xs) = B : A : zS xs
当我测试函数zS
时,结果应为:
zS [B, B, A, A, B, B, B, A, B ] --> [B, A, A, B, A, B ]
但它不起作用。此外,当我编译代码时,Haskell返回一个警告,如下所示:
Warning:
Pattern match(es) are overlapped
In an equation for 'zS':
我该如何解决这个问题?
答案 0 :(得分:4)
<强> TL; DR 强>
当您定义具有多个模式的函数时,应该在开头定义过于具体的模式,并在结尾定义更广泛的模式。
<强>解释强>
在你的情况下,
zS (B:xs) = B : zS xs
已匹配任何以B
开头的列表。所以,
zS (B:B:xs) = B : zS xs
zS (B:A:xs) = B : A : zS xs
已经与zS (B:xs) = B : zS xs
本身匹配。这就是Haskell通过说
Pattern match(es) are overlapped
要解决此问题,请在开头定义特定模式,例如
zS :: [El] -> [El]
zS [] = []
zS (B:B:xs) = B : zS xs
zS (B:A:xs) = B : A : zS xs
zS (A:xs) = A : zS xs
zS (B:xs) = B : zS xs
注意:您的代码有错误,
zS (B:B:xs) = B : zS xs
在这里,如果您找到两个匹配项,并且无论重复多次B
,您都会包含B
。相反,你可以像这样递归
zS (B:B:xs) = zS (B:xs)
这样
zS (B:A:xs) = B : A : zS xs
将负责为您重复B
。