[Haskell-cafe] Trouble with the ST monad

Andre Nathan andre at digirati.com.br
Mon Dec 29 13:57:56 EST 2008


On Sun, 2008-12-21 at 16:47 -0800, Ryan Ingram wrote:
> The problem is that you are trying to return a mutable array out of an
> ST computation.  This lets the "mutability" of the computation escape.
>  That's what the "s" type variable is for;  without it, runST is just
> unsafePerformIO.

I'm trying something similar now... I have defined a data type for
mutable matrices as

  data STMatrix s a = STMatrix
    { elements :: Array Int (STArray s Int a)
    , nrows    :: Int
    , ncols    :: Int
    }

and one for immutable matrices:

  data Matrix a = Matrix
    { elements :: Array Int (Array int a)
    , nrows    :: Int
    , ncols    :: Int
    }

What I wanted was a way to freeze an STMatrix into a Matrix so that I
could work with it out of the ST monad after doing all of the
modifications I need on the elements.

I came up with the following:

  doFreeze :: STMatrix s a -> ST s (Matrix a)
  doFreeze mat = do
    let m = nrows mat
        n = ncols mat
    rows <- foldM (freezeRow mat) [] [m-1,m-2..0]
    return $ listMatrix (m, n) rows
    where
      freezeRow mat rs i = do
        r <- unsafeFreeze (elements mat ! i)
        return (r:rs)

where "listMatrix" builds a Matrix from a list of Arrays.

However, when I this:

  freezeMatrix = runST . doFreeze

I get the "less polymorphic than expected" error from ghc. I fail to see
why though. Since "freezeRow" returns a list of immutable Arrays, where
is the mutability of the computation escaping here?

Thanks in advance,
Andre



More information about the Haskell-Cafe mailing list