{-# LANGUAGE RankNTypes #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Array.ST -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) -- -- Maintainer : libraries@haskell.org -- Stability : experimental -- Portability : non-portable (uses Data.Array.MArray) -- -- Mutable boxed and unboxed arrays in the 'Control.Monad.ST.ST' monad. -- ----------------------------------------------------------------------------- module Data.Array.ST ( -- * Boxed arrays STArray, -- instance of: Eq, MArray runSTArray, -- * Unboxed arrays STUArray, -- instance of: Eq, MArray runSTUArray, -- * Overloaded mutable array interface module Data.Array.MArray, ) where import Data.Array.Base ( STUArray, UArray, unsafeFreezeSTUArray ) import Data.Array.MArray import Control.Monad.ST ( ST, runST ) import GHC.Arr ( STArray, Array, unsafeFreezeSTArray ) -- | 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 :: (forall s . ST s (STArray s i e)) -> Array i e runSTArray :: forall i e. (forall s. ST s (STArray s i e)) -> Array i e runSTArray forall s. ST s (STArray s i e) st = forall a. (forall s. ST s a) -> a runST (forall s. ST s (STArray s i e) st forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= forall s i e. STArray s i e -> ST s (Array i e) 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 :: (forall s . ST s (STUArray s i e)) -> UArray i e runSTUArray :: forall i e. (forall s. ST s (STUArray s i e)) -> UArray i e runSTUArray forall s. ST s (STUArray s i e) st = forall a. (forall s. ST s a) -> a runST (forall s. ST s (STUArray s i e) st forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= forall s i e. STUArray s i e -> ST s (UArray i e) 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).