[project @ 2004-01-05 16:03:34 by simonmar]
authorsimonmar <unknown>
Mon, 5 Jan 2004 16:03:34 +0000 (16:03 +0000)
committersimonmar <unknown>
Mon, 5 Jan 2004 16:03:34 +0000 (16:03 +0000)
Add runSTArray and runSTUArray, as suggested by John Meacham.
runSTUArray showed up an interesting deficiency in the type system
(see comments for details).

Data/Array/ST.hs

index 507ba60..e8de28f 100644 (file)
@@ -16,9 +16,11 @@ module Data.Array.ST (
 
    -- * Boxed arrays
    STArray,            -- instance of: Eq, MArray
+   runSTArray,
 
    -- * Unboxed arrays
    STUArray,           -- instance of: Eq, MArray
+   runSTUArray,
    castSTUArray,       -- :: STUArray s i a -> ST s (STUArray s i b)
 
    -- * Overloaded mutable array interface
@@ -28,12 +30,47 @@ module Data.Array.ST (
 import Prelude
 
 import Data.Array.MArray
-import Data.Array.Base ( STUArray, castSTUArray )
+import Data.Array.Base ( STUArray, castSTUArray, UArray, unsafeFreezeSTUArray )
+import Control.Monad.ST        ( ST, runST )
 
 #ifdef __HUGS__
 import Hugs.ST         ( STArray )
 #endif
 
 #ifdef __GLASGOW_HASKELL__
-import GHC.Arr         ( STArray )
+import GHC.Arr         ( STArray, Array )
 #endif
+
+-- | A safe way to create and work with a mutable array before returning an
+-- immutable array for later perusal.  This function avoids copying
+-- the array before returning it - it uses 'unsafeFreeze' internally, but
+-- this wrapper is a safe interface to that function.
+--
+runSTArray :: (Ix i)
+          => (forall s . ST s (STArray s i e))
+          -> Array i e
+runSTArray st = runST (st >>= unsafeFreeze)
+
+-- | A safe way to create and work with an unboxed mutable array before
+-- returning an immutable array for later perusal.  This function
+-- avoids copying the array before returning it - it uses
+-- 'unsafeFreeze' internally, but this wrapper is a safe interface to
+-- that function.
+--
+runSTUArray :: (Ix i)
+          => (forall s . ST s (STUArray s i e))
+          -> UArray i e
+runSTUArray st = runST (st >>= unsafeFreezeSTUArray)
+
+
+-- INTERESTING... this is the type we'd like to give to runSTUArray:
+--
+-- runSTUArray :: (Ix i, IArray UArray e, 
+--             forall s. MArray (STUArray s) e (ST s))
+--        => (forall s . ST s (STUArray s i e))
+--        -> UArray i e
+--
+-- Note the quantified constraint.  We dodged the problem by using
+-- unsafeFreezeSTUArray directly in the defn of runSTUArray above, but
+-- this essentially constrains us to a single unsafeFreeze for all STUArrays
+-- (in theory we might have a different one for certain element types).