Haskell-由于我不明白的原因而用尽的模式

问题描述 投票:2回答:2

因此,我正在尝试编写一个函数,该函数给定两个整数列表,将每个列表的第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

我真的看不到我所缺少的内容,因为它不能与我输入的任何内容一起使用。

haskell design-patterns functional-programming matching
2个回答
1
投票

[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

0
投票

虽然在这种情况下使用import Data.Function(on) addEven :: Integral a => [a] -> [a] -> [a] addEven = addList `on` filter even 是非常本能的,也许两次使用filter,然后对结果求和,对于大型列表而言可能效率不高。我们为什么不一次完成所有工作以进行更改。.]

filter
© www.soinside.com 2019 - 2024. All rights reserved.