0
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 带有任何有限长度的列表。但是我所有的实现返回都是[]. 为什么会这样,我该如何解决?

4

3 回答 3

5

您的递归基本情况返回[], 和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]]),但实际上这些边缘情况可能不会发生在您身上。

于 2017-09-06T14:07:29.547 回答
3

您的基本情况太基本了......该函数将递归地消耗所有行。当它一直向下递归堆栈时,剩下的是空列表,即没有行的列表。这将返回一个空结果。

但是,回到递归堆栈,每一层都应该用+. 好吧,但是用空列表压缩任何列表都会导致一个空列表!

您可以通过三种方式解决此问题:

  • 为单行矩阵添加一个额外的基本情况。如果只有一行,结果应该就是那一行,对吧?

    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
    
于 2017-09-06T13:55:16.117 回答
1

我相信您也可以使用以下单个foldr1操作进行操作;

listsAdd :: (Foldable t, Num c) => t [c] -> [c]
listsAdd =  foldr1 (zipWith (+))

*Main> listsAdd [[1,2,3],[4,5,6]]
[5,7,9]
于 2017-09-06T14:27:00.193 回答