因此,我正在尝试编写一个函数,该函数给定两个整数列表,将每个列表的第i个偶数相加并在另一个列表中返回它们。如果列表中的一个没有第i个偶数,则考虑为0。例如,如果列表是[1,2,1,4,6]和[2,2],则返回[4,6,6]([2 + 2,4 + 2,6 + 0])。我有以下代码:
addEven :: [Int] -> [Int] -> [Int]
addEeven [] [] = []
addEeven (x:xs) [] = filter (\g -> g `mod`2 == 0) (x:xs)
addEven [] (y:ys) = filter (\g -> g `mod` 2 == 0) (y:ys)
addEven (x:xs) (y:ys) = (a + b):(addEven as bs)
where
(a:as) = filter (\g -> g `mod` 2 == 0) (x:xs)
(b:bs) = filter (\g -> g `mod` 2 == 0) (y:ys)
当使用上一个示例运行该命令时,我得到:
[4,6*** Exception: ex.hs:(4,1)-(8,101): Non-exhaustive patterns in function addEven
我真的看不到我所缺少的内容,因为它不能与我输入的任何内容一起使用。
[A filter
可能会消除元素,因此filter (\g -> g
mod 2 == 0)
不会说返回任何元素,因此模式(a:as)
和(b:bs)
可能会失败。
话虽如此,我认为您在这里使问题变得太复杂了。您可以首先定义一个辅助函数,该函数添加列表的两个元素:
addList :: Num a => [a] -> [a] -> [a]
addList (x:xs) (y:ys) = (x+y) : addList xs ys
addList xs [] = xs
addList [] ys = ys
然后,我们对两个参数进行过滤,并创建一个看起来像下面的函数addEven
:
addEven :: Integral a => [a] -> [a] -> [a]
addEven xs ys = addList (filter even xs) (filter even ys)
或带有on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
:
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
虽然在这种情况下使用import Data.Function(on)
addEven :: Integral a => [a] -> [a] -> [a]
addEven = addList `on` filter even
是非常本能的,也许两次使用filter
,然后对结果求和,对于大型列表而言可能效率不高。我们为什么不一次完成所有工作以进行更改。.]
filter