Question

How to apply fold functions only finite number of times, instead of folding the entire list? For example, this incomplete fold would sum up only first 3 numbers, leaving the rest untouched:

foldlN 3 (+) [1..5] -- [6,4,5]
Was it helpful?

Solution

It seems simple just to fold on a part of list, then cons it to the rest of the list:

foldlN :: Int -> (a -> a -> a) -> [a] -> [a]
foldlN n f xs = (foldl1 f $ take n xs) : drop n xs

Result in REPL:

*Main> foldlN 3 (+) [1..5]
[6,4,5]

If you worry that taking and then dropping from the same list is a double job, you can rewrite with splitAt:

foldlN n f xs = (foldl1 f $ fst t) : snd t
  where t = splitAt n xs

Note the type of the function, you can't base your fold on foldl, because you can't have a list [[1,2,3],4,5,6] in Haskell.

OTHER TIPS

First, folding a list with (+) doesn't produce a list, it produces a single answer. Perhaps you want scanl or scanr?

scanl (+) 0 [1..5] -- [0, 0+1, 0+1+2, 0+1+2+3, ...]

So if you wanted to add only the first 3 numbers, that would be the 4th element of this list;

(scanl (+) 0 [1..5]) !! 3

Alternatively, you could just cut the list down to 3 elements:

foldl (+) 0 (take 3 [1..5])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top