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@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-----