请注意,([0]++)
它与 相同(0:)
,这将使它看起来更整洁并为我们节省一两纳秒。(我在拿纳秒开玩笑——没有人能分辨出什么时候比纳秒快,但无论如何这种方式更好。)
让我们首先考虑制作您需要的列表。我们想要
postponeLists [[1,2,3], [7,6,8], [10,20,30,40]]
= [[1,2,3], [0,7,6,8], [0,0,10,20,30,40]]
= [1,2,3] : ones that should have zero in front of them
这对定义来说已经足够了:
postponeLists [] = []
postponeLists (l:ls) = l : map (0:) (postponeLists ls)
现在你说
foldl (zipWith +) [] [[1,2,3],[0,7,6,8],[0,0,0,3,4]]
但你的意思是
foldl (zipWith (+)) [] [[1,2,3],[0,7,6,8],[0,0,0,3,4]]
但不幸的是,这给了你[]
因为zipWith
一旦任何列表用完元素就会停止。我们需要一些不停地压缩它们的方法。
解决方案1:找到最长的一个,maxlength
使用take maxlength.(++ repeat 0)
解决方案2:编写另一个不会停止的zipWith函数。
我更喜欢方案2。我们看一下定义zipWith
zipWith :: (a->b->c) -> [a]->[b]->[c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _ _ = [] -- here's the problem - it stops as soon as any list is empty
好的,我们不要停下来:
zipWithMore :: (a -> a -> a) -> [a] -> [a] -> [a]
zipWithMore f (a:as) (b:bs) = f a b : zipWithMore f as bs
zipWithMore f [] bs = bs -- if there's more in bs, use that
zipWithMore f as [] = as -- if there's more in as, use that
现在您可以替换zipWith (+)
为zipWithMore (+)
. 我会把重点留给你。