“多重声明”模式与通配符匹配时出错
出于学习目的,我尝试编写自己的 zipWith 函数实现。但是,我在使用 _
的边缘情况下遇到了模式匹配问题。首先我将描述好的情况,然后描述坏的情况。希望有人能够解释为什么他们的行为不同。谢谢
如果我按如下方式编写 zipWith 函数,它就可以工作(注意第 2 行和第 3 行中与空列表匹配的边缘情况的顺序):-
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipwith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
在 GHCI 中编译:-
ghci> :l ZipWith.hs
[1 of 1] Compiling Main ( ZipWith.hs, interpreted )
好的,上面的没问题,但是如果我交换 GHCI 周围边缘情况的模式匹配,则会在第 2 行和第 4 行抛出“多重声明”错误。
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ _ [] = []
zipwith' _ [] _ = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
在 GHCI 中编译:-
ZipWith.hs:4:0:
Multiple declarations of `Main.zipWith''
Declared at: ZipWith.hs:2:0
ZipWith.hs:4:0
Failed, modules loaded: none.
我被难住了......
- 看看第 2 行和第 4 行上的模式,它们似乎相互排斥,但我显然在这里遗漏了一些基本的东西,
- 为什么切换第 2 行和第 3 行的模式会导致编译错误消失。
For learning purposes I am trying to write my own implementation of the zipWith
function. However, I am hitting an issue with pattern matching on edge cases with _
. First I will describe the good case, then the bad case. Hopefully someone will be able to explain why they behave differently. Thanks
If I write the zipWith
function as follows, it works (Note the order of the edge cases matching empty list on lines 2 & 3):-
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipwith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
Compiling in GHCI:-
ghci> :l ZipWith.hs
[1 of 1] Compiling Main ( ZipWith.hs, interpreted )
Ok, the above is fine, yet if I swap the pattern matching for the edge cases around GHCI throws 'Multiple declarations of' error for lines 2 and 4.
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ _ [] = []
zipwith' _ [] _ = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
Compiling in GHCI:-
ZipWith.hs:4:0:
Multiple declarations of `Main.zipWith''
Declared at: ZipWith.hs:2:0
ZipWith.hs:4:0
Failed, modules loaded: none.
I'm stumped...
- Looking at the patterns on lines 2 and 4 they seem mutually exclusive but i'm obviously missing something fundamental here
- Why would switching the patterns on lines 2 and 3 cause the compilation error to go away.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
错误消息并不是抱怨模式重叠(在两个空列表的情况下,您的模式确实重叠,但这既不是问题,也不是问题),而是 zipWith 函数的多个定义。
原因是在第二种情况下,您有一个
zipWith
定义,后跟一个不相关的zipwith
定义(请注意小写的w
),后跟一个新的、相互冲突的zipWith
定义。换句话说,这是一个简单的错字。 (我确实花了一段时间才看到——这是一个偷偷摸摸的打字错误)The error message isn't complaining about overlapping patterns (your patterns do overlap in the case of two empty lists, but that's neither the problem, nor a problem), but multiple definitions of the
zipWith
function.The reason for that is that in your second case you have one definition of
zipWith
followed by an unrelated definition ofzipwith
(note the lower casew
), followed by a new, conflicting definition ofzipWith
. In other words it's a simple typo. (Did take me a while to see though - quite a sneaky typo)