lstsAdder :: [[Integer]] -> [Integer]
lstsAdder [] = []
lstsAdder (x:xs) = zipWith (+) x (lstsAdder xs)
正如标题所说,我希望它递归地添加 this: [[a,b,c],[d,e,f]]
like this: [a+d,b+e,c+f]
,并且 this 带有任何有限长度的列表。但是我所有的实现返回都是[]
. 为什么会这样,我该如何解决?
您的递归基本情况返回[]
, 和length (zipWith f a b) = min (length a) (length b)
. 这意味着您的结果将始终具有长度 0。标识元素为min
+infinity,标识元素为(+)
,0
因此一种可能的基本情况是repeat 0
。
您还可以查看数据的先决条件是否允许您执行类似的操作
import Data.List (transpose)
lstsAdder = map sum . transpose
它具有不同的边缘情况行为(作为一个示例输入QuickCheck
给出[[0,0],[0]]
),但实际上这些边缘情况可能不会发生在您身上。
您的基本情况太基本了......该函数将递归地消耗所有行。当它一直向下递归堆栈时,剩下的是空列表,即没有行的列表。这将返回一个空结果。
但是,回到递归堆栈,每一层都应该用+
. 好吧,但是用空列表压缩任何列表都会导致一个空列表!
您可以通过三种方式解决此问题:
为单行矩阵添加一个额外的基本情况。如果只有一行,结果应该就是那一行,对吧?
lstsAdder [] = []
lstsAdder [r] = r
lstsAdder (x:xs) = zipWith (+) x $ lstsAdder xs
在压缩步骤中用零填充缺失的元素。
lstsAdder [] = []
lstsAdder (x:xs) = x ^+^ lstsAdder xs
infixrl 6 ^+^
(^+^) :: [a] -> [a] -> [a]
xs^+^[] = xs
[]^+^ys = ys
(x:xs)^+^(y:ys) = (x+y) : (xs^+^ys)
给出基本情况的无限零列表:
lstsAdder [] = repeat 0
lstsAdder (x:xs) = zipWith (+) x $ lstsAdder xs
我相信您也可以使用以下单个foldr1
操作进行操作;
listsAdd :: (Foldable t, Num c) => t [c] -> [c]
listsAdd = foldr1 (zipWith (+))
*Main> listsAdd [[1,2,3],[4,5,6]]
[5,7,9]