I'm new to Haskell. I want to add an array field to my data structure, something like this:

data Level = Level
    { a :: Data.Array.Ix
    } deriving (Show, Eq, Ord)

But I don't know how to declare the field's type. It keeps giving me errors.

2 Answers

Jon Purdy On Best Solutions

Ix is not a type, but a typeclass that the Data.Array functions use to provide indexing of different shapes of array. If you want an array itself, you need to use the Array type. It has two type parameters: the type of indices into the array, such as Int (for a 1D array) or (Int, Int) (for a 2D array), and the type of elements.

So for example, a 1D array of characters would have the type Array Int Char; you can create arrays using functions like array, listArray, or accumArray, e.g. in GHCi:

-- A 5-element array of characters
> example1 = listArray (0, 4) "abcde"

> example1 ! 2

-- A 3-element array of strings
> example2 = array (0, 2) [(0, "this"), (1, "that"), (2, "other")] :: Array Int String

> example2 ! 2

> example2 ! 3
*** Exception: Ix{Int}.index: Index (3) out of range ((0,2))

A 2D array of integers would have the type Array (Int, Int) Int:

-- A 3x3 matrix of numbers
> example3 = listArray ((0, 0), (2, 2)) [1..9]

> example3
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)]

> elems example3

> bounds example3

> example3 ! (1, 2)

So for instance if you wanted to represent a Tic-Tac-Toe board, you might use something along the lines of:

import Data.Array

data Board = Board
    { boardCells :: Array (Int, Int) Move
    } deriving (Show, Eq, Ord)

data Move = Empty | X | O

Which types you use depend on the actual problem you’re solving, of course.

Leif Metcalf On

Data.Array.Ix is not a type, but rather a class of types which can be used as an index for an array (like Int).

You may want to use either Array from Data.Array.IArray (For immutable arrays), or IOArray / STArray from Data.Array.IO or Data.Array.ST (For mutable arrays). Something like this would work:

import Data.Array.IArray

type SomeType = String

data Level = Level
  { a :: Data.Array Int SomeType
  } deriving (Show, Eq, Ord)