import Data.Array
stride :: Int -> Int -> Int
stride count cols = ceiling (fromIntegral count / fromIntegral cols)
type Direction = Int -> Int -> Int -> Int -> Int
right :: Direction
right count cols x y = y * cols + x
down :: Direction
down count cols x y = x * stride count cols + y
data Options = Options { cols :: Int, direction :: Direction }
options :: Options
options = Options 1 right
table :: Options -> [a] -> Array (Int,Int) (Maybe a)
table (Options cols dir) xs
= listArray newRange (map f (range newRange))
where count = length xs
rows = stride count cols
newRange = ((0,0),(rows-1,cols-1))
f (y, x)
| ix < count = Just (xs !! ix)
| otherwise = Nothing
where ix = dir count cols x y
Это дает нам довольно идиоматическое приближение вашего исходного запроса с необязательными аргументами:
*Main> table options { cols = 3 } [1..10]
listArray ((0,0),(3,2)) [Just 1, Just 2, Just 3
,Just 4, Just 5, Just 6
,Just 7, Just 8, Just 9
,Just 10,Nothing,Nothing]
*Main> table options { direction = down, cols = 3 } [1..10]
listArray ((0,0),(3,2)) [Just 1,Just 5,Just 9
,Just 2,Just 6,Just 10
,Just 3,Just 7,Nothing
,Just 4,Just 8,Nothing]
Я оставил промежуточные результаты в виде массива, так как вы указали, что вы планируете форматировать их в виде таблицы или тегов ul.