[Haskell] help with IOArray
Bertram Felgenhauer
bertram.felgenhauer at googlemail.com
Sun Aug 19 11:22:59 EDT 2007
robert bauer wrote:
> I have an IOArray, but it doesn't work the way I expected it to.
>
> I defined
>
> newMem s = newIOArray (0, size-1) 0
>
> and then
>
> x = newMem 30
>
> then
>
> do {
> y <- x
> ; v <- readIOArray y 2
> ; print v
> ; writeIOArray y 2 20
> ; v <- readIOArray y 2
> ; print v
> }
>
> this resulted in 0, 2 as expected.
>
> however, then
>
> do {
> y <- x
> ; v <- readIOArray y 20
> ; print v
> }
>
> results in 0
>
> I thought the IOArray was basically a static structure?
yes it is. However, 'x' is not an IOArray. Its type is (after
defaulting)
x :: IO (IOArray Int Int)
It represents an IO action that constructs a *new* array.> do {
so
> do {
> y <- x
> ; v <- readIOArray y 20
> ; print v
> }
constrcts a new array and finds its 20th element, which was
initialized to 0.
The problem you have is dealing with global variables in Haskell.
There are two major approaches.
a) Construct the variable once and pass it explicitely as an argument to
all functions. (In other words, don't use global variables at all.)
> main = do {
> mem <- newMem
> func1 mem
> func2 mem
> }
This is simple, easy to understand, but it doesn't scale well.
To make it scale better you can define a data type for the
global state.
> data GlobalState = GS { mem :: IOArray Int Int }
This record can then easily be extended with new fields as they
come up.
Finally you can get rid of the explicit 'mem' (or 'state') arguments
by using a state monad transformer (StateT).
b) Use actual global variables. See
http://haskell.org/haskellwiki/Top_level_mutable_state
for further information.
http://haskell.org/haskellwiki/Global_variables is also interesting.
HTH,
Bertram
More information about the Haskell
mailing list