[project @ 2005-10-13 11:09:50 by ross]
[haskell-directory.git] / Data / Array / ST.hs
index 507ba60..828ae63 100644 (file)
@@ -6,7 +6,7 @@
 -- 
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
--- Portability :  non-portable
+-- Portability :  non-portable (uses Data.Array.MArray)
 --
 -- Mutable boxed and unboxed arrays in the 'Control.Monad.ST.ST' monad.
 --
@@ -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,48 @@ 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 )
+import Hugs.Array      ( Array )
+import Hugs.ST         ( STArray, unsafeFreezeSTArray )
 #endif
 
 #ifdef __GLASGOW_HASKELL__
-import GHC.Arr         ( STArray )
+import GHC.Arr         ( STArray, Array, unsafeFreezeSTArray )
 #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 >>= unsafeFreezeSTArray)
+
+-- | 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).