Hakan Alp
Hakan Alp

Reputation: 121

Challenging list comprehension question in Haskell

I am trying to make a nested list like that with list comprehension:

[[1,2,3],[4,5,6],[7,8,9]] 

I coded something like:

take 3 [take 3 [i .. ] | i <- [1 ..]]

but it gives this:

[[1,2,3],[2,3,4],[3,4,5]]

How can I make it like the upper one?

Upvotes: 1

Views: 98

Answers (3)

Elmex80s
Elmex80s

Reputation: 3504

Something like this:

let n = 4 in take n [take n [(i * n + 1) .. ] | i <- [0 .. ]]

Which gives

[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]

Using list comprehension only you can do this

let n = 4 in [[((i - 1) * n + 1) .. (i * n)] | i <- [1 .. n]]

Upvotes: 4

Redu
Redu

Reputation: 26161

You may generalize to n items like

chunksOf :: Int -> [[Int]]
chunksOf n = take n [[(i-n+1)..i] | i <- [1..], i `mod` n == 0]

Prelude> chunksOf 3
[[1,2,3],[4,5,6],[7,8,9]]
Prelude> chunksOf 4
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
Prelude> chunksOf 6
[[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24],[25,26,27,28,29,30],[31,32,33,34,35,36]]

Upvotes: 2

Jeff Foster
Jeff Foster

Reputation: 44706

The syntax [1,4 ..] gives you an infinite list 1,4,7 (and so on). Once you've realized that bit of syntax exists then this becomes much simpler!

take 3 [ [x,x+1,x+2] | x <- [1,4 ..] ]

Should give

[[1,2,3],[4,5,6],[7,8,9]]

Upvotes: 7

Related Questions