I have the following tuple representing a 2D matrix in Haskell
let a =[(1,2,3),(4,5,6),(7,8,9)]
How can I access each index individually? (e.g. a[1][1], a[0][1] etc.)
Is there a better way to interpret 2D arrays in haskell?

- 582
- 2
- 9
- 26
-
Consider using the [repa](http://hackage.haskell.org/package/repa) library. Here's a [tutorial](http://www.haskell.org/haskellwiki/Numeric_Haskell:_A_Repa_Tutorial). – Mikhail Glushenkov Oct 26 '13 at 02:18
-
Or [Data.Array](http://hackage.haskell.org/package/array-0.4.0.1/docs/Data-Array.html) from the standard library. – Mikhail Glushenkov Oct 26 '13 at 02:38
2 Answers
Here's an example of how to create and index an immutable 2D array using the standard Data.Array
module:
Prelude> import Data.Array
Prelude Data.Array> let a = array ((0,0),(2,2)) [((i,j),3*i+j)| i <- [0..2], j <- [0..2]]
Prelude Data.Array> a ! (1,1)
4
More information can be found on the Haskell Wiki.

- 14,928
- 3
- 52
- 65
If you're going to be doing this a lot --- working with matrices, arrays, etc. --- then it's probably best to follow one of Mikhail's suggestions.
If you're simply curious about how to go about doing this though, it basically comes down to pattern matching. One thing you can do is use the !!
function to get a zero-indexed element from a list (the row in this case) and then you would have to pattern match to get the specific element from the tuple.
For example, in the following code, getRow
fetches the specific row using !!
, and then getElem
returns the particular tuple element, so that ultimately getElem a 1 1 == 5
for example. You would of course have to add some code to handle out-of-bounds indices:
getRow :: [(Integer, Integer, Integer)] -> Int -> (Integer, Integer, Integer)
getRow matrix row = matrix !! (row :: Int)
getElem :: [(Integer, Integer, Integer)] -> Int -> Int -> Integer
getElem matrix row column
| column == 0 = x
| column == 1 = y
| column == 2 = z
where (x, y, z) = getRow matrix row

- 36,800
- 16
- 93
- 123
-
You should definitely def `type Row = (Integer,Integer,Integer)` if actually keeping to the rows-as-tuples approach. And `getRow` is pretty redundant here, you could simply define it `getRow=(!!)`. Also, I tend to prefer pattern matching to equality comparison, e.g. `| 0<-column = x` rather than `| column==0 = x`. That's disputable here, though. – leftaroundabout Oct 26 '13 at 14:56
-
@leftaroundabout Thanks, that's all very true, but I didn't submit my code sample as some sort of bastion of Haskell code style. If the OP was having trouble figuring out how to do this simple task, I didn't want to muddy the waters with added complexity which might hinder his understanding. By explicitly defining `getRow`, I meant to clearly convey how it is he could fetch a particular row from this matrix structure, for example. – Jorge Israel Peña Oct 26 '13 at 22:27