([0]++)
は と同じであることに注意してください(0:)
。これにより、見栄えが良くなり、1 つか 2 ナノ秒節約できます。(私はナノ秒のことで冗談を言っています.何かがいつナノ秒速いかを人間は知ることができませんが、とにかくこの方法の方が良いです.)
まず、必要なリストの作成について考えてみましょう。私たちは欲しい
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
OK、それではやめましょう:
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 (+)
。オチはお任せします。