for loops and 2d arrays in haskell

hi all Since I am very new to haskell and still learning, I hope I will not annoy poeple by asking the following question. 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]); } } ,Fernan -- Public PGP/GnuPG key (http://www.fernski.com) pub 1024D/3576CA71 2006-02-02 Fernan Bolando Key fingerprint = FDFE C9A8 FFED C1A5 2F5C EFEB D595 AF1C 3576 CA71

On 1/19/07, Fernan Bolando
hi all
Since I am very new to haskell and still learning, I hope I will not annoy poeple by asking the following question.
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]); } }
Do you mean:
for(i = 0; i < imax; i++){ for(n = 0; n < nmax; n++){ printf("%i:%i = %f\n", i,n,array[i][n]); } }
If so, how about: sequence [ putStr (show i ++ ":" ++ show n ++ " = " show arr!(i,n) | (i,n) <- indices arr ] -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

On 1/19/07, Sebastian Sylvan
On 1/19/07, Fernan Bolando
wrote: hi all
Since I am very new to haskell and still learning, I hope I will not annoy poeple by asking the following question.
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]); } }
Do you mean:
for(i = 0; i < imax; i++){ for(n = 0; n < nmax; n++){ printf("%i:%i = %f\n", i,n,array[i][n]); } }
If so, how about:
sequence [ putStr (show i ++ ":" ++ show n ++ " = " show arr!(i,n) | (i,n) <- indices arr ]
Sorry: sequence [ putStrLn (show i ++ ":" ++ show n ++ " = " show arr!(i,n)) | (i,n) <- indices arr ] -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

On 1/19/07, Sebastian Sylvan
On 1/19/07, Sebastian Sylvan
wrote: On 1/19/07, Fernan Bolando
wrote: hi all
Since I am very new to haskell and still learning, I hope I will not annoy poeple by asking the following question.
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]); } }
Do you mean:
for(i = 0; i < imax; i++){ for(n = 0; n < nmax; n++){ printf("%i:%i = %f\n", i,n,array[i][n]); } }
If so, how about:
sequence [ putStr (show i ++ ":" ++ show n ++ " = " show arr!(i,n) | (i,n) <- indices arr ]
Sorry: sequence [ putStrLn (show i ++ ":" ++ show n ++ " = " show arr!(i,n)) | (i,n) <- indices arr ]
Bah, it's way to early, forgot another parenthesis: sequence [ putStrLn (show i ++ ":" ++ show n ++ " = " show (arr!(i,n)) ) | (i,n) <- indices arr ] -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

Fernan Bolando 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]); } } *%* ghci
* / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done. Prelude>* :m + Data.Array *Prelude Data.Array>* let a = listArray ((0,0),(2,2)) [1..9] This is how it looks by default: *Prelude Data.Array>* a array ((0,0),(2,2)) [((0,0),1),((0,1),2),((0,2),3),((1,0),4),((1,1),5),((1,2),6),((2,0),7),((2,1),8),((2,2),9)] 'assocs' builds the corresponding assoc list: *Prelude Data.Array> *assocs a [((0,0),1),((0,1),2),((0,2),3),((1,0),4),((1,1),5),((1,2),6),((2,0),7),((2,1),8),((2,2),9)] 'map show' converts it into a list of strings: *Prelude Data.Array>* map show $ assocs a ["((0,0),1)","((0,1),2)","((0,2),3)","((1,0),4)","((1,1),5)","((1,2),6)","((2,0),7)","((2,1),8)","((2,2),9)"] 'unlines' to convert to a single string where each list element is one line, and 'putStrLn' to print it: *Prelude Data.Array> *putStrLn $ unlines $ map show $ assocs a **((0,0),1) ((0,1),2) ((0,2),3) ((1,0),4) ((1,1),5) ((1,2),6) ((2,0),7) ((2,1),8) ((2,2),9) * *To get the exact same output, replace 'show' with a custom-built function. * Prelude Data.Array>* putStrLn $ unlines $ map (\((i,j),v)-> show i++":"++show j++"="++show v) $ assocs a 0:0=1 0:1=2 0:2=3 1:0=4 1:1=5 1:2=6 2:0=7 2:1=8 2:2=9

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
participants (4)
-
Fernan Bolando
-
Ketil Malde
-
Sebastian Sylvan
-
Yitzchak Gale