[Haskell-cafe] Mutable arrays

John Lato jwlato at gmail.com
Tue Feb 5 21:15:48 EST 2008


Hmm.  It looks like I forgot a step, and it probably would segfault as
given.  That's what I get for mucking about with unsafe* functions.
How about this?

let frozen_ary = unsafeFreeze myArray
let ary_max = foldl1' max $ elems frozen_ary
in ary_max `seq` map (1/ary_max) $ unsafeThaw frozen_ary

This sequence doesn't modify the array object after freezing, except
to call unsafeThaw on it, and there is no need to access the frozen
array after unsafeThaw.  Even so, piling another unsafe function on to
clean up the mess from the first unsafe function strikes me as an
anti-pattern (even though the docs seem to indicate that "unsafeThaw
write unsafeFreeze" could work).  Furthermore, I can't say what would
happen to any of the original references to myArray, other than that
it's better not to use them.

I'm still mostly a noob, but assuming it works, your version with
inlinePerformIO looks better to me, even with the caveats of
inlinePerformIO.

John

On Feb 5, 2008 7:26 PM, Stefan O'Rear <stefanor at cox.net> wrote:
> On Tue, Feb 05, 2008 at 06:00:38PM -0600, John Lato wrote:
> > -- let ary_max = foldl1' max $ elems $ unsafeFreeze myArray
> >
> > If you use a boxed array type (IOArray or STArray) for myArray, and
> > compiled with GHC, no copying is necessary (you may need to use type
> > annotations to guarantee this).  Then use the foldl' function to get
> > array_max, and map it onto the original mutable array.  I think it
> > would be safe provided that you calculate ary_max before you start to
> > modify the array, which is true for normalization.
>
> Eek!  unsafeFreeze isn't a type cast, it actually modifies flags in the
> heap object which are used by the generational garbage collector.  It's
> quite concievable that you could get segfaults by modifying a boxed
> array after passing it to unsafeFreeze.
>
> This, I believe, would work:
>
> let ary_max = foldl1' max [ inlinePerformIO (readArray myArray ix)
>                             | ix <- range (inlinePerformIO (getBounds myArray)) ]
>
> But it's equally untested.
>
> Stefan
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.6 (GNU/Linux)
>
> iD8DBQFHqQzTFBz7OZ2P+dIRAujzAJ49RDMKtgzrMZ9TxRyXge0hSFZHgwCdGAXM
> 8rQy4Fufodehcj5cxoSOoVM=
> =wHxm
> -----END PGP SIGNATURE-----
>
>


More information about the Haskell-Cafe mailing list