"Pattern match is redundant" 在列表推导中使用输入列表参数时
"Pattern match is redundant" when using input list argument inside list comprehension
这是我的代码:
example = [1,-4,7,12]
positiveSum :: [Int] -> Int
positiveSum (x) = 0
positiveSum (x:xs) = result
where
result = sum [y+y | y <- xs, y > 0]
main = do
print (positiveSum example)
当我 运行 它时,我得到:
Main.hs:5:1: warning: [-Woverlapping-patterns]
Pattern match is redundant
In an equation for `positiveSum': positiveSum (x : xs) = ...
|
5 | positiveSum (x:xs) = result
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^...
我不能在列表理解中使用 'xs',我不明白为什么。这是一个参考,我应该可以使用它。为什么它是多余的?
编辑:
答案解决了问题,我正在匹配第一个 (x)。另外,我把自己弄糊涂了,两次应用 sum 。这是正确的代码:
positiveSum :: [Int] -> Int
positiveSum [] = 0
positiveSum xs = result
where
result = sum [x | x <- xs, x > 0]
模式匹配从上到下,所以每次调用 positiveSum
returns 0
。由于第一个规则的模式是 positiveSum (x) = 0
,它匹配 所有 ,因为每个值都可以绑定到 x
。通过将该规则设为最后一条,您可以避免此问题:
positiveSum :: [Int] -> Int
positiveSum (x:xs) = result
where
result = sum [y+y | y <- xs, y > 0]
positiveSum (x) = 0
使用此代码,如果参数没有尾部,我们只会回退到 0
情况,从而导致预期的行为。
你似乎认为 positiveSum (x) = 0
只会匹配空列表的情况,但实际上它会匹配任何东西,这使得下一行变得多余,因为它永远不会被尝试。你打算在那里写 positiveSum [] = 0
。另外,请注意你的第二种情况,即使它现在 运行,也会丢弃列表的头部,你可能不是故意的。
你不需要区分空列表和non-empty列表:你可以计算过滤列表的总和:
positiveSum :: [Int] -> Int
positiveSum xs = sum [y | y <- xs, y > 0]
此处 xs
模式与 所有 可能的列表相匹配:空或非空。 y
将枚举 xs
的所有项目,如果 y > 0
,我们产生该值。然后我们计算该列表的总和。对于空列表 sum
将 return 0
,因此无论 xs
是否为空,并且存在满足 y > 0
谓词的元素,它将 return 一个值。
另一种选择是使用 filter :: (a -> Bool) -> [a] -> [a]
,从而确定总和:
positiveSum :: [Int] -> Int
positiveSum = sum . <strong>filter (0 <)</strong>
这是我的代码:
example = [1,-4,7,12]
positiveSum :: [Int] -> Int
positiveSum (x) = 0
positiveSum (x:xs) = result
where
result = sum [y+y | y <- xs, y > 0]
main = do
print (positiveSum example)
当我 运行 它时,我得到:
Main.hs:5:1: warning: [-Woverlapping-patterns]
Pattern match is redundant
In an equation for `positiveSum': positiveSum (x : xs) = ...
|
5 | positiveSum (x:xs) = result
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^...
我不能在列表理解中使用 'xs',我不明白为什么。这是一个参考,我应该可以使用它。为什么它是多余的?
编辑:
答案解决了问题,我正在匹配第一个 (x)。另外,我把自己弄糊涂了,两次应用 sum 。这是正确的代码:
positiveSum :: [Int] -> Int
positiveSum [] = 0
positiveSum xs = result
where
result = sum [x | x <- xs, x > 0]
模式匹配从上到下,所以每次调用 positiveSum
returns 0
。由于第一个规则的模式是 positiveSum (x) = 0
,它匹配 所有 ,因为每个值都可以绑定到 x
。通过将该规则设为最后一条,您可以避免此问题:
positiveSum :: [Int] -> Int
positiveSum (x:xs) = result
where
result = sum [y+y | y <- xs, y > 0]
positiveSum (x) = 0
使用此代码,如果参数没有尾部,我们只会回退到 0
情况,从而导致预期的行为。
你似乎认为 positiveSum (x) = 0
只会匹配空列表的情况,但实际上它会匹配任何东西,这使得下一行变得多余,因为它永远不会被尝试。你打算在那里写 positiveSum [] = 0
。另外,请注意你的第二种情况,即使它现在 运行,也会丢弃列表的头部,你可能不是故意的。
你不需要区分空列表和non-empty列表:你可以计算过滤列表的总和:
positiveSum :: [Int] -> Int
positiveSum xs = sum [y | y <- xs, y > 0]
此处 xs
模式与 所有 可能的列表相匹配:空或非空。 y
将枚举 xs
的所有项目,如果 y > 0
,我们产生该值。然后我们计算该列表的总和。对于空列表 sum
将 return 0
,因此无论 xs
是否为空,并且存在满足 y > 0
谓词的元素,它将 return 一个值。
另一种选择是使用 filter :: (a -> Bool) -> [a] -> [a]
,从而确定总和:
positiveSum :: [Int] -> Int
positiveSum = sum . <strong>filter (0 <)</strong>