在Haskell的列表中的Zip元素

时间:2015-03-22 07:51:55

标签: list haskell

我在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':

我该如何解决这个问题?

1 个答案:

答案 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