A quick search on Hoogle showed that there is no such function. On the other hand, it was replied that there is one in the split package, called chunksOf.

However, you can do it on your own

group :: Int -> [a] -> [[a]]
group _ [] = []
group n l
  | n > 0 = (take n l) : (group n (drop n l))
  | otherwise = error "Negative or zero n"

Of course, some parentheses can be removed, I left there here for understanding what the code does:

The base case is simple: whenever the list is empty, simply return the empty list.

The recursive case tests first if n is positive. If n is 0 or lower we would enter an infinite loop and we don't want that. Then we split the list into two parts using take and drop: take gives back the first n elements while drop returns the other ones. Then, we add the first n elements to the list obtained by applying our function to the other elements in the original list.

Answer from Mihai Maruseac on Stack Overflow
🌐
Hackage
hackage.haskell.org › package › split-0.2.5 › docs › Data-List-Split.html
Data.List.Split - Hackage - Haskell
chunksOf n splits a list into length-n pieces. The last piece will be shorter if n does not evenly divide the length of the list.
Discussions

Split list into groups of n in Haskell - Code Review Stack Exchange
The ready made function chunksOf works very well. When tasked to create 3 elements in sublists with 11 elements in the source list, two elements will be in the last sublist of the result. More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
list - Nested chunksOf in Haskell? - Stack Overflow
A function like nestedChunksOf can't be done directly in Haskell, at least not one which operates on normal lists. The depth of the list is part of the type, so you can't have an arbitrary depth specified by a parameter. But what you can do is nest chunksOf. More on stackoverflow.com
🌐 stackoverflow.com
Subdividing a list in haskell - Stack Overflow
Actually, is splitEvery still recommended? :1:1: Warning: In the use of ‘splitEvery’ Deprecated: "Use chunksOf." 2015-03-06T17:20:51.067Z+00:00 More on stackoverflow.com
🌐 stackoverflow.com
list - split elements into groups haskell - Stack Overflow
Hey Im new to functional programming and learning haskell. I'm wondering whether will i be able to split elements in a list and grouping them in two's. I already saw the splitAt operations and it More on stackoverflow.com
🌐 stackoverflow.com
September 2, 2014
🌐
Reddit
reddit.com › r/haskell › is there a data.list.chunk :: int -> [a] -> [[a]]?
r/haskell on Reddit: is there a Data.List.chunk :: Int -> [a] -> [[a]]?
March 11, 2012 -

I've come across some older Haskell code which refers to Data.List.chunk with apparent type signature Int -> [a] -> [[a]].

Hoogle doesn't turn up anything - the closest being Data.Text.chunksOf.

Is there a different/better alternative?

🌐
Hackage
hackage.haskell.org › package › split-0.2.5 › docs › Data-List-Split-Internals.html
Data.List.Split.Internals
However, in the interest of simplicity ... This is in line with split's design philosophy of having efficiency as a non-goal. ... chunksOf n splits a list into length-n pieces....
Top answer
1 of 2
13

There are Data.List.Split.chunksOf and Data.List.Grouping.splitEvery implementations of this routine in specialized packages (and a number included in other application packages: search by Int -> [a] -> [[a]] signature on Hayoo).

I think splitEvery implementation is pretty elegant:

splitEvery :: Int -> [a] -> [[a]]
splitEvery _ [] = []
splitEvery n xs = as : splitEvery n bs 
  where (as,bs) = splitAt n xs
2 of 2
1

The ready made function chunksOf works very well. When tasked to create 3 elements in sublists with 11 elements in the source list, two elements will be in the last sublist of the result. The following function also includes trailers.

mklsts n = takeWhile (not.null) . map (take n) . iterate (drop n)

I use this as pairs with a 2 for n and no n parameter. Pairs rock.

Edit/Add 4/12/2018

The match up of iterate and splitOn is one made in hell. In the questioner above, placing splitOn in a lambda may have compounded the problems. It is possible to make splitOn work with iterate but you have to ditch the fst of the tuple produced. That defeats the entire purpose. It is way cleaner and easier to use drop n with iterate. The results are the same. That's what the preceding function does. Otherwise, it's the same idea.

Here is a novel way of producing the identical results using tails imported from Data.List in a list comprehension. It picks up stragglers, too.

ts n ls = [take n l|l<-init$tails ls,odd (head l)]

The parameters are size-of-sublist and list

Edit 4/17/2018

Well, since I had some time at work a list comprehension version that does not use tails, a recursive version and a map version.

ttx s ls=[take s.drop x$ls|x<-[0,s..s*1000]]

Recursive

tkn n []=[];tkn n xs=[take n xs]++(tkn n $ drop n xs)

Map

tp n ls=takeWhile(not.null)$   map(take n.flip drop ls) [0,n..]

The list comprehension is virtually infinite. Change [0,s..s*200] to [0,s..] for true infinity. The recursive is, of course, inherently infinite and the map function uses a big takeWhile (not.null) to end itself.

🌐
Stackage
stackage.org › lts-24.10 › hoogle
Hoogle Search :: Stackage Server
Within LTS Haskell 24.10 (ghc-9.10.2) Note that Stackage only displays results for the latest LTS and Nightly snapshot. Learn more. chunksOf :: Int -> Text -> [Text] O(n) Splits a Text into components of length k. The last element may be shorter than the other chunks, depending on the length ...
🌐
Hackage
hackage.haskell.org › package › vector-split › docs › Data-Vector-Split.html
Data.Vector.Split - Hackage - Haskell
chunksOf n splits a vector into length-n pieces. The last piece will be shorter if n does not evenly divide the length of the vector. If n <= 0, chunksOf n l returns an infinite list of empty vectors.
🌐
Hackage
hackage.haskell.org › package › extra › docs › Data-List-Extra.html
Data.List.Extra
\xs -> repeatedly (splitAt 3) xs == chunksOf 3 xs \xs -> repeatedly word1 (trim xs) == words xs \xs -> repeatedly line1 xs == lines xs
Find elsewhere
🌐
GitHub
github.com › ndreynolds › advent-of-code › blob › master › 2018 › haskell › Day15.hs
advent-of-code/2018/haskell/Day15.hs at master · ndreynolds/advent-of-code
displayMap battleMap = intercalate "\n" $ chunksOf (xMax + 1) squares · where · squares = [ displaySquare (battleMap ! (x, y)) | y <- [0 .. yMax], x <- [0 .. xMax] ] xMax = maximum $ map fst coords · yMax = maximum $ map snd coords · coords = Map.keys battleMap ·
Author   ndreynolds
Top answer
1 of 4
12

A function like nestedChunksOf can't be done directly in Haskell, at least not one which operates on normal lists. The depth of the list is part of the type, so you can't have an arbitrary depth specified by a parameter.

But what you can do is nest chunksOf.

If we define chunksOf like this:

chunksOf :: Int -> [a] -> [[a]]
chunksOf _ [] = []
chunksOf n xs = fxs : chunksOf n sxs
    where (fxs, sxs) = splitAt n xs

We can then nest it:

Main> :l test.hs
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> chunksOf 3 [1,1,1,2,2,2,3,3,3,4,4,4]
[[1,1,1],[2,2,2],[3,3,3],[4,4,4]]
*Main> chunksOf 2 $ chunksOf 3 [1,1,1,2,2,2,3,3,3,4,4,4]
[[[1,1,1],[2,2,2]],[[3,3,3],[4,4,4]]]

I hope that accomplishes what you wanted!

2 of 4
6

As stated in the other answers, this can't be done directly as in Haskell you always need to know the type of an expression and thus distinguish between [a], [[a]] etc. However, using polymorphic recursion you can define a data type that allows such arbitrary nesting by wrapping each level in a constructor:

data NestedList a = Value a | Nested (NestedList [a])
  deriving (Show)

So just Value is isomorphic to a, Nested (Value ...) is isomorphic to [a], double Nested to [[a]] etc. Then you can implement

chunksOf :: Int -> [a] -> [[a]]
...

nestedChunksOf :: [Int] -> [a] -> NestedList a
nestedChunksOf [] xs = Nested (Value xs)
nestedChunksOf (c:cs) xs = Nested (nestedChunksOf cs $ chunksOf c xs)

And indeed

print $ nestedChunksOf [3, 2] [1,1,1,2,2,2,3,3,3,4,4,4]

outputs

Nested (Nested (Nested (Value [[[1,1,1],[2,2,2]],[[3,3,3],[4,4,4]]])))
🌐
Hackage
hackage.haskell.org › package › array-chunks
array-chunks: Lists of chunks
Lists of chunks. This is similar to the Cons List provided by Data.List, but it is more useful as a target for a builder since the chunks are cache coherent · For package maintainers and hackage trustees
🌐
DEV Community
dev.to › deciduously › comment › cmh2
Haskell: import Data.Bool (bool) import Data.List (intercalate) import Dat... - DEV Community
July 9, 2019 - 153 becomes [1,5,3] intoDigits :: Int -> [Int] intoDigits 0 = [] intoDigits n = intoDigits (div n 10) ++ [mod n 10] -- e.g [1,5,3] becomes 153 fromDigits :: [Int] -> Int fromDigits = foldl addDigit 0 where addDigit num d = 10 * num + d -- Primary -- Ideally, this'd have returned a Maybe String, but spec and all isCubic :: Int -> String isCubic n = let cubes = map (^3) $ intoDigits n in bool (failString) (show n) (length cubes <= 3 && (sum cubes) == n) -- Secondary showCubes :: String -> String showCubes s = let maybeDigits = filter (isJust) $ map (\s -> readMaybe s :: Maybe Int) $ words s splitLongerThanThrees = map fromDigits $ concat $ map (chunksOf 3) $ map intoDigits $ map fromJust $ maybeDigits justCubes = filter (/= failString) $ map isCubic splitLongerThanThrees in bool (failString) (intercalate " " justCubes) (length justCubes > 0)
🌐
Blogger
neilmitchell.blogspot.com › 2016 › 01 › a-simple-haskell-function.html
Neil Mitchell's Blog (Haskell etc): A simple Haskell function
January 14, 2016 - Acknowledgements: Thanks to Andrey Mokhov for providing the repo, figuring out all the weird corner cases with ar, and distilling it down into a Haskell problem. ... Andrey Mokhov said... Thanks for the detailed analysis! Surprisingly interesting for what initially appeared to be a boring function. I imagine the following generalisation to be useful: chunksOfSizeBy :: (a -> Int) -> Int -> [a] -> [[a]] So that chunksOfSize == chunksOfSizeBy length Then chunksOfSizeBy id makes sense too.
🌐
Lambda
lambda.xyz › blog › chunky-bacon
Splitting a list into chunks with unfoldr 〜 lambda fairy
March 13, 2017 - I’m quite fond of the unfoldr function in Haskell.
🌐
Hackage
hackage.haskell.org › package › split-0.2.0.0 › docs › Data-List-Split.html
Data.List.Split
chunksOf n splits a list into length-n pieces. The last piece will be shorter if n does not evenly divide the length of the list. If n <= 0, chunksOf n l returns an infinite list of empty lists.
🌐
GitHub
github.com › haskell-streaming › streaming
GitHub - haskell-streaming/streaming: An optimized general monad transformer for streaming applications, with a simple prelude of functions
chunksOf :: Monad m => Int -> Producer a m r -> Stream (Producer a m) m r concats :: Monad m => Stream (Producer a m) m r -> Producer a m r · Of course, as soon as you grasp the general form of succession you are already in possession of the most basic concrete form: a simple succession of individual Haskell values one after another, the effectful list or sequence.
Starred by 172 users
Forked by 30 users
Languages   Haskell 87.7% | HTML 12.3% | Haskell 87.7% | HTML 12.3%
🌐
Hackage
hackage.haskell.org › package › containers › docs › Data-Sequence.html
Data.Sequence - Hackage - Haskell.org
chunksOf :: Int -> Seq a -> Seq (Seq a) takeWhileL :: (a -> Bool) -> Seq a -> Seq a · takeWhileR :: (a -> Bool) -> Seq a -> Seq a · dropWhileL :: (a -> Bool) -> Seq a -> Seq a · dropWhileR :: (a -> Bool) -> Seq a -> Seq a ·