I would use list comprehensions to manipulate the indices.
printArray arr =
unlines [unwords [show (arr ! (x, y)) | x <- [0..5]] | y <- [0..5]]
Question
I'm messing around with printing a random 2d array of Ints, in this simple image format (PPM)
0 1 0 0 1
1 0 0 1 0
0 1 1 0 0
0 1 1 1 0
0 0 0 1 0
Below is my code, which works, but seems like way too much code for such a simple operation. Is there a better way to do this?
import System.Random
import Data.Array.IArray
main = do
g <- newStdGen
let img = listArray ((0,0),(5,5)) ( myRands g ) :: Array (Int,Int) Int
putStrLn $ printArray img
myRands :: RandomGen g => g -> [Int]
myRands g = randomRs (0,1) g
make2dRange :: Int -> Int -> Int -> Int -> [(Int,Int)]
make2dRange x1 y1 x2 y2 = range ((x1,y1),(x2,y2))
printArray :: ( Array (Int,Int) Int ) -> String
printArray arr = unlines rows
where rows = map (unwords . map (show . (!) arr)) rowIndices
rowIndices = map ( \y -> make2dRange 0 y 5 y ) [0..5]
Other than the obvious, of course (array dimensions are hardcoded, for example)
Solution
I would use list comprehensions to manipulate the indices.
printArray arr =
unlines [unwords [show (arr ! (x, y)) | x <- [0..5]] | y <- [0..5]]
OTHER TIPS
chunksOf :: Int -> [e] -> [[e]]
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.
using chunksOf my implementation would be..
printArray arr = mapM_ (putStrLn . unwords) $ map (map show) $ chunksOf 5 arr
usage:
Prelude System.Random Data.List Data.List.Split> printArray [0..25]
0 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