[Haskell-cafe] for loops and 2d arrays in haskell

Yitzchak Gale gale at sefer.org
Fri Jan 19 06:31:40 EST 2007


Hi Fernan,

You wrote:
> > what is the simplest way to implement the following code in haskell?
> > it's just printing the contents of 2D array.
> >
> > for(i = 0; i < imax; i++){
> >     for(n = 0; n < nmax; n++){
> >         printf("%i:%i = %f\n", array[i][n]);
> >     }
> > }

There are many different ways of representing the
concept of a "2D array" in Haskell.

Sebastian Sylvan wrote:
> sequence [ putStrLn (show i ++ ":" ++ show n ++ " = " show (arr!(i,n)) )
>                | (i,n) <- indices arr ]

Ketil Malde wrote:
> putStrLn $ unlines $ map (\((i,j),v)-> show
> i++":"++show j++"="++show v) $ assocs a

Sebastian and Ketil are both thinking of the type:

import Data.Array
arr :: Array (Int, Int) Int

Ketil also showed how to build the array to begin with.

That type is quite similar to arrays in C, except that
they are immutable. There are also mutable arrays,
which are almost exactly like arrays in C, but they
are a bit more clumsy to work with.

There are other ways of representing 2D arrays
that are less similar to arrays in C, and perhaps
more natural in Haskell.

For simplicity, let me define a function that prints
one element, corresponding to your "printf":

showElt :: Show a => Int -> Int -> a -> String
showElt i j x = show i ++ ":" ++ show j ++ "=" ++ show x

This is exactly what Sebastian and Ketil used.
Note that I am not requiring that the array contains
integers anymore - any type that Haskell knows how
to print (any "instance of the Show class") will do.

One way to represent your array is the type:

arr :: Show a => [[a]]

You could build it like this:

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

You could print it like this:

putStrLn $ unlines [showElt i n x | (row,i) <- zip arr [0..], (x,n) <-
zip row [0..]]

Another way is as an association list (this is what Ketil got
out of the Array type using the assocs function):

arr :: Show a => [((Int, Int), a]

arr = zip [(i,n) | i <- [0..2], n <-  [0..2]] [1,2,3,4,5,6,7,8,9]

putStrLn $ unlines [showElt i n x | ((i,n),x) <- arr]

If you also need random access to the array, you should
look at Data.Sequence and Data.IntMap from the standard
library (in addition to mutable arrays, as mentioned above).

Regards,
Yitz


More information about the Haskell-Cafe mailing list