How to bundle values into set length lists in Haskell?

285 views Asked by At

Trying to write a function in Haskell that bundles a list of xs into lists of size n e.g. the result of bundle 3 [1..10] should be [[1,2,3],[4,5,6],[7,8,9],[10]].

I know the type should be

bundle :: Int -> [a] -> [[a]]

and needs to satisfy something like

concat $ bundle n xs == xs
length xss > 1 ==> all (\xs -> n  == length xs) (init xss)

but when I come to actually try to implement it I get stuck. I imagine I need to use foldl but can't think of what function to apply.

1

There are 1 answers

0
Zeta On BEST ANSWER

Well, you can use splitAt, e.g.

bundle :: Int -> [a] -> [[a]]
bundle _ [] = []
bundle n xs = as : bundle n bs
  where (as, bs) = splitAt n xs

however, you should make sure n is positive, otherwise you'll end up with an infinite list of empty lists. This function holds your properties: splitAt n returns a pair where the first part of the tuple has exactly n elements. Since all but the last list entry are created that way, your second property holds. The first property holds for obvious reasons.

However, those "bundles" are usually called "chunks". The package split provides the fitting function chunksOf, which does exactly the same:

import Data.List.Split (chunksOf)

bundle :: Int -> [a] -> [[a]]
bundle = chunksOf