Haskell中列表的部分折叠
如何只应用有限次函数,而不是折叠整个列表?例如,这个不完整的折叠将只对前3个数字求和,其余数字保持不变:Haskell中列表的部分折叠,haskell,fold,Haskell,Fold,如何只应用有限次函数,而不是折叠整个列表?例如,这个不完整的折叠将只对前3个数字求和,其余数字保持不变: foldlN 3 (+) [1..5] -- [6,4,5] 只需将列表的一部分折叠起来,然后将其与列表的其余部分合并,似乎很简单: foldlN :: Int -> (a -> a -> a) -> [a] -> [a] foldlN n f xs = (foldl1 f $ take n xs) : drop n xs 结果为REPL: *Main>
foldlN 3 (+) [1..5] -- [6,4,5]
只需将列表的一部分折叠起来,然后将其与列表的其余部分合并,似乎很简单:
foldlN :: Int -> (a -> a -> a) -> [a] -> [a]
foldlN n f xs = (foldl1 f $ take n xs) : drop n xs
结果为REPL:
*Main> foldlN 3 (+) [1..5]
[6,4,5]
如果您担心从同一列表中获取然后删除是一项双重任务,您可以使用以下方法重写:
请注意函数的类型,您不能将折叠基于foldl
,因为在Haskell中不能有列表[[1,2,3],4,5,6]
。首先,使用(+)
折叠列表不会生成列表,而是生成一个答案。也许您想要scanl
或scanr
scanl (+) 0 [1..5] -- [0, 0+1, 0+1+2, 0+1+2+3, ...]
因此,如果你只想添加前3个数字,这将是这个列表的第4个元素
(scanl (+) 0 [1..5]) !! 3
或者,您可以将列表缩减为3个元素:
foldl (+) 0 (take 3 [1..5])
foldl (+) 0 (take 3 [1..5])