diff --git a/Data/Array.hs b/Data/Array.hs
--- a/Data/Array.hs
+++ b/Data/Array.hs
@@ -1,10 +1,10 @@
-
+{-# LANGUAGE Trustworthy #-}
 -----------------------------------------------------------------------------
 -- |
--- Module      :  Data.Array 
+-- Module      :  Data.Array
 -- Copyright   :  (c) The University of Glasgow 2001
 -- License     :  BSD-style (see the file libraries/base/LICENSE)
--- 
+--
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  provisional
 -- Portability :  portable
@@ -16,31 +16,30 @@
 -- those defined below, but with more general types, and also defines
 -- 'Array' instances of the relevant classes.  To use that more general
 -- interface, import "Data.Array.IArray" but not "Data.Array".
+--
 -----------------------------------------------------------------------------
 
-module  Data.Array 
-
-    ( 
+module Data.Array (
     -- * Immutable non-strict arrays
     -- $intro
-      module Data.Ix		-- export all of Ix 
-    , Array 			-- Array type is abstract
+    module Data.Ix, -- export all of Ix
+    Array,          -- Array type is abstract
 
     -- * Array construction
-    , array	    -- :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
-    , listArray     -- :: (Ix a) => (a,a) -> [b] -> Array a b
-    , accumArray    -- :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
+    array,          -- :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
+    listArray,      -- :: (Ix a) => (a,a) -> [b] -> Array a b
+    accumArray,     -- :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
     -- * Accessing arrays
-    , (!)           -- :: (Ix a) => Array a b -> a -> b
-    , bounds        -- :: (Ix a) => Array a b -> (a,a)
-    , indices       -- :: (Ix a) => Array a b -> [a]
-    , elems         -- :: (Ix a) => Array a b -> [b]
-    , assocs        -- :: (Ix a) => Array a b -> [(a,b)]
+    (!),            -- :: (Ix a) => Array a b -> a -> b
+    bounds,         -- :: (Ix a) => Array a b -> (a,a)
+    indices,        -- :: (Ix a) => Array a b -> [a]
+    elems,          -- :: (Ix a) => Array a b -> [b]
+    assocs,         -- :: (Ix a) => Array a b -> [(a,b)]
     -- * Incremental array updates
-    , (//)          -- :: (Ix a) => Array a b -> [(a,b)] -> Array a b
-    , accum         -- :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
+    (//),           -- :: (Ix a) => Array a b -> [(a,b)] -> Array a b
+    accum,          -- :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
     -- * Derived arrays
-    , ixmap         -- :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a b
+    ixmap,          -- :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a b
 
     -- Array instances:
     --
@@ -49,16 +48,16 @@
     --   (Ix a, Ord b) => Ord  (Array a b)
     --   (Ix a, Show a, Show b) => Show (Array a b)
     --   (Ix a, Read a, Read b) => Read (Array a b)
-    -- 
+    --
 
     -- Implementation checked wrt. Haskell 98 lib report, 1/99.
-
-    ) where
+  ) where
 
 import Data.Ix
+import Data.Typeable ()
 
 #ifdef __GLASGOW_HASKELL__
-import GHC.Arr                    -- Most of the hard work is done here
+import GHC.Arr  -- Most of the hard work is done here
 #endif
 
 #ifdef __HUGS__
@@ -66,11 +65,8 @@
 #endif
 
 #ifdef __NHC__
-import Array -- Haskell'98 arrays
+import Array    -- Haskell'98 arrays
 #endif
-
--- For instances:
-import Data.Typeable    ()
 
 {- $intro
 Haskell provides indexable /arrays/, which may be thought of as functions
diff --git a/Data/Array/Base.hs b/Data/Array/Base.hs
--- a/Data/Array/Base.hs
+++ b/Data/Array/Base.hs
@@ -12,7 +12,7 @@
 -- Module      :  Data.Array.Base
 -- 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 (MPTCs, uses Control.Monad.ST)
@@ -32,17 +32,17 @@
 import Foreign.StablePtr
 
 #ifdef __GLASGOW_HASKELL__
-import GHC.Arr		( STArray, unsafeIndex )
+import GHC.Arr          ( STArray, unsafeIndex )
 import qualified GHC.Arr as Arr
 import qualified GHC.Arr as ArrST
-import GHC.ST		( ST(..), runST )
+import GHC.ST           ( ST(..), runST )
 import GHC.Base
-import GHC.Word		( Word(..) )
-import GHC.Ptr		( Ptr(..), FunPtr(..), nullPtr, nullFunPtr )
-import GHC.Float	( Float(..), Double(..) )
-import GHC.Stable	( StablePtr(..) )
-import GHC.Int		( Int8(..),  Int16(..),  Int32(..),  Int64(..) )
-import GHC.Word		( Word8(..), Word16(..), Word32(..), Word64(..) )
+import GHC.Word         ( Word(..) )
+import GHC.Ptr          ( Ptr(..), FunPtr(..), nullPtr, nullFunPtr )
+import GHC.Float        ( Float(..), Double(..) )
+import GHC.Stable       ( StablePtr(..) )
+import GHC.Int          ( Int8(..),  Int16(..),  Int32(..),  Int64(..) )
+import GHC.Word         ( Word8(..), Word16(..), Word32(..), Word64(..) )
 #if __GLASGOW_HASKELL__ >= 611
 import GHC.IO           ( IO(..), stToIO )
 import GHC.IOArray      ( IOArray(..),
@@ -140,7 +140,7 @@
     return marr
 
 
-{-# INLINE array #-} 
+{-# INLINE array #-}
 
 {-| Constructs an immutable array from a pair of bounds and a list of
 initial associations.
@@ -176,10 +176,10 @@
 gives an array-bounds error, but 'bounds' still yields the bounds with
 which the array was constructed.
 -}
-array 	:: (IArray a e, Ix i) 
-	=> (i,i)	-- ^ bounds of the array: (lowest,highest)
-	-> [(i, e)]	-- ^ list of associations
-	-> a i e
+array   :: (IArray a e, Ix i)
+        => (i,i)        -- ^ bounds of the array: (lowest,highest)
+        -> [(i, e)]     -- ^ list of associations
+        -> a i e
 array (l,u) ies
     = let n = safeRangeSize (l,u)
       in unsafeArray (l,u)
@@ -239,11 +239,11 @@
 --
 -- More precisely, we'd like to write this:
 --   listUArray :: (forall s. MArray (STUArray s) e (ST s), Ix i)
---	        => (i,i) -> [e] -> UArray i e
+--              => (i,i) -> [e] -> UArray i e
 --   listUArray lu = runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
 --   {-# RULES listArray = listUArray
 -- Then we could call listUArray at any type 'e' that had a suitable
--- MArray instance.  But sadly we can't, because we don't have quantified 
+-- MArray instance.  But sadly we can't, because we don't have quantified
 -- constraints.  Hence the mass of rules below.
 
 -- I would like also to write a rule for listUArrayST (or listArray or
@@ -261,7 +261,7 @@
    = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Char
 "listArray/UArray/Int"       listArray
    = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Int
-"listArray/UArray/Word"      listArray	
+"listArray/UArray/Word"      listArray
    = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Word
 "listArray/UArray/Ptr"       listArray
    = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray (Ptr a)
@@ -318,7 +318,7 @@
 
 {-# INLINE accumArray #-}
 
-{-| 
+{-|
 Constructs an immutable array from a list of associations.  Unlike
 'array', the same index is allowed to occur multiple times in the list
 of associations; an /accumulating function/ is used to combine the
@@ -518,9 +518,9 @@
 -----------------------------------------------------------------------------
 -- Showing IArrays
 
-{-# SPECIALISE 
-    showsIArray :: (IArray UArray e, Ix i, Show i, Show e) => 
-		   Int -> UArray i e -> ShowS
+{-# SPECIALISE
+    showsIArray :: (IArray UArray e, Ix i, Show i, Show e) =>
+                   Int -> UArray i e -> ShowS
   #-}
 
 showsIArray :: (IArray a e, Ix i, Show i, Show e) => Int -> a i e -> ShowS
@@ -554,7 +554,7 @@
 #endif
 #ifdef __HUGS__
     unsafeAt (UArray _ _ _ arr) i =
-	testBit (readByteArray arr (bOOL_INDEX i)::BitSet) (bOOL_SUBINDEX i)
+        testBit (readByteArray arr (bOOL_INDEX i)::BitSet) (bOOL_SUBINDEX i)
 #endif
     {-# INLINE unsafeReplace #-}
     unsafeReplace arr ies = runST (unsafeReplaceUArray arr ies)
@@ -942,7 +942,7 @@
     -- | Returns the number of elements in the array
     getNumElements :: Ix i => a i e -> m Int
 
-    -- | Builds a new array, with every element initialised to the supplied 
+    -- | Builds a new array, with every element initialised to the supplied
     -- value.
     newArray    :: Ix i => (i,i) -> e -> m (a i e)
 
@@ -960,9 +960,9 @@
     unsafeWrite :: Ix i => a i e -> Int -> e -> m ()
 
     {-# INLINE newArray #-}
-	-- The INLINE is crucial, because until we know at least which monad 	
-	-- we are in, the code below allocates like crazy.  So inline it,
-	-- in the hope that the context will know the monad.
+        -- The INLINE is crucial, because until we know at least which monad
+        -- we are in, the code below allocates like crazy.  So inline it,
+        -- in the hope that the context will know the monad.
     newArray (l,u) initialValue = do
         let n = safeRangeSize (l,u)
         marr <- unsafeNewArray_ (l,u)
@@ -1038,7 +1038,7 @@
 {-# INLINE getElems #-}
 -- | Return a list of all the elements of a mutable array
 getElems :: (MArray a e m, Ix i) => a i e -> m [e]
-getElems marr = do 
+getElems marr = do
   (_l, _u) <- getBounds marr
   n <- getNumElements marr
   sequence [unsafeRead marr i | i <- [0 .. n - 1]]
@@ -1047,7 +1047,7 @@
 -- | Return a list of all the associations of a mutable array, in
 -- index order.
 getAssocs :: (MArray a e m, Ix i) => a i e -> m [(i, e)]
-getAssocs marr = do 
+getAssocs marr = do
   (l,u) <- getBounds marr
   n <- getNumElements marr
   sequence [ do e <- unsafeRead marr (safeIndex (l,u) n i); return (i,e)
@@ -1057,7 +1057,7 @@
 -- | Constructs a new array derived from the original array by applying a
 -- function to each of the elements.
 mapArray :: (MArray a e' m, MArray a e m, Ix i) => (e' -> e) -> a i e' -> m (a i e)
-mapArray f marr = do 
+mapArray f marr = do
   (l,u) <- getBounds marr
   n <- getNumElements marr
   marr' <- newArray_ (l,u)
@@ -1401,7 +1401,7 @@
     {-# INLINE newArray_ #-}
     newArray_ arrBounds = newArray arrBounds 0
     {-# INLINE unsafeRead #-}
-    unsafeRead (STUArray _ _ _ marr#) (I# i#) = ST $ \s1# -> 
+    unsafeRead (STUArray _ _ _ marr#) (I# i#) = ST $ \s1# ->
         case readInt64Array# marr# i# s1# of { (# s2#, e# #) ->
         (# s2#, I64# e# #) }
     {-# INLINE unsafeWrite #-}
@@ -1539,16 +1539,16 @@
         return (STUArray l u n marr)
     newArray_ bounds = unsafeNewArray_ bounds
     unsafeRead (STUArray _ _ _ marr) i = do
-	let ix = bOOL_INDEX i
-	    bit = bOOL_SUBINDEX i
-	w <- readMutableByteArray marr ix
-	return (testBit (w::BitSet) bit)
+        let ix = bOOL_INDEX i
+            bit = bOOL_SUBINDEX i
+        w <- readMutableByteArray marr ix
+        return (testBit (w::BitSet) bit)
     unsafeWrite (STUArray _ _ _ marr) i e = do
-	let ix = bOOL_INDEX i
-	    bit = bOOL_SUBINDEX i
-	w <- readMutableByteArray marr ix
-	writeMutableByteArray marr ix
-	    (if e then setBit (w::BitSet) bit else clearBit w bit)
+        let ix = bOOL_INDEX i
+            bit = bOOL_SUBINDEX i
+        w <- readMutableByteArray marr ix
+        writeMutableByteArray marr ix
+            (if e then setBit (w::BitSet) bit else clearBit w bit)
 
 instance MArray (STUArray s) Char (ST s) where
     getBounds = getBoundsMBArray
@@ -1684,7 +1684,7 @@
 
 bOOL_SCALE :: Int -> Int
 bOOL_SCALE n = (n + bitSetSize - 1) `div` bitSetSize
- 
+
 bOOL_INDEX :: Int -> Int
 bOOL_INDEX i = i `div` bitSetSize
 
@@ -1733,7 +1733,7 @@
 -- freeze it (and, subsequently mutate it, I suspect).
 
 {- |
-   Converts an mutable array into an immutable array.  The 
+   Converts an mutable array into an immutable array.  The
    implementation may either simply cast the array from
    one type to the other without copying the array, or it
    may take a full copy of the array.
@@ -1812,10 +1812,10 @@
 -- thaw it (and, subsequently mutate it, I suspect).
 
 {- |
-   Converts an immutable array into a mutable array.  The 
+   Converts an immutable array into a mutable array.  The
    implementation may either simply cast the array from
    one type to the other without copying the array, or it
-   may take a full copy of the array.  
+   may take a full copy of the array.
 
    Note that because the array is possibly not copied, any subsequent
    modifications made to the mutable version of the array may be
@@ -1904,3 +1904,4 @@
 #elif __HUGS__
 castSTUArray (STUArray l u n marr) = return (STUArray l u n marr)
 #endif
+
diff --git a/Data/Array/IArray.hs b/Data/Array/IArray.hs
--- a/Data/Array/IArray.hs
+++ b/Data/Array/IArray.hs
@@ -1,9 +1,10 @@
+{-# LANGUAGE Trustworthy #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Array.IArray
 -- 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.Base)
@@ -15,14 +16,14 @@
 --
 -----------------------------------------------------------------------------
 
-module Data.Array.IArray ( 
+module Data.Array.IArray (
     -- * Array classes
     IArray,     -- :: (* -> * -> *) -> * -> class
 
     module Data.Ix,
 
     -- * Immutable non-strict (boxed) arrays
-    Array,    
+    Array,
 
     -- * Array construction
     array,      -- :: (IArray a e, Ix i) => (i,i) -> [(i, e)] -> a i e
@@ -43,8 +44,9 @@
     -- * Derived arrays
     amap,       -- :: (IArray a e', IArray a e, Ix i) => (e' -> e) -> a i e' -> a i e
     ixmap,      -- :: (IArray a e, Ix i, Ix j) => (i,i) -> (i -> j) -> a j e -> a i e
- )  where
+  ) where
 
 import Data.Ix
 import Data.Array (Array)
 import Data.Array.Base
+
diff --git a/Data/Array/IO.hs b/Data/Array/IO.hs
--- a/Data/Array/IO.hs
+++ b/Data/Array/IO.hs
@@ -5,7 +5,7 @@
 -- Module      :  Data.Array.IO
 -- 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)
@@ -15,23 +15,24 @@
 -----------------------------------------------------------------------------
 
 module Data.Array.IO (
-   -- * @IO@ arrays with boxed elements
-   IOArray,		-- instance of: Eq, Typeable
+    -- * @IO@ arrays with boxed elements
+    IOArray,             -- instance of: Eq, Typeable
 
-   -- * @IO@ arrays with unboxed elements
-   IOUArray,		-- instance of: Eq, Typeable
-   castIOUArray,	-- :: IOUArray i a -> IO (IOUArray i b)
+    -- * @IO@ arrays with unboxed elements
+    IOUArray,            -- instance of: Eq, Typeable
+    castIOUArray,        -- :: IOUArray i a -> IO (IOUArray i b)
 
-   -- * Overloaded mutable array interface
-   module Data.Array.MArray,
+    -- * Overloaded mutable array interface
+    module Data.Array.MArray,
 
-   -- * Doing I\/O with @IOUArray@s
-   hGetArray,		-- :: Handle -> IOUArray Int Word8 -> Int -> IO Int
-   hPutArray,		-- :: Handle -> IOUArray Int Word8 -> Int -> IO ()
- ) where
+    -- * Doing I\/O with @IOUArray@s
+    hGetArray,           -- :: Handle -> IOUArray Int Word8 -> Int -> IO Int
+    hPutArray,           -- :: Handle -> IOUArray Int Word8 -> Int -> IO ()
+  ) where
 
 import Data.Array.Base
-import Data.Array.IO.Internals
+import Data.Array.IO.Internals hiding ( castIOUArray )
+import qualified Data.Array.Unsafe as U ( castIOUArray )
 import Data.Array.MArray
 import System.IO.Error
 
@@ -59,13 +60,13 @@
 -- | Reads a number of 'Word8's from the specified 'Handle' directly
 -- into an array.
 hGetArray
- 	:: Handle		-- ^ Handle to read from
-	-> IOUArray Int Word8	-- ^ Array in which to place the values
-	-> Int			-- ^ Number of 'Word8's to read
-	-> IO Int
-		-- ^ Returns: the number of 'Word8's actually 
-		-- read, which might be smaller than the number requested
-		-- if the end of file was reached.
+        :: Handle               -- ^ Handle to read from
+        -> IOUArray Int Word8   -- ^ Array in which to place the values
+        -> Int                  -- ^ Number of 'Word8's to read
+        -> IO Int
+                -- ^ Returns: the number of 'Word8's actually
+                -- read, which might be smaller than the number requested
+                -- if the end of file was reached.
 
 hGetArray handle (IOUArray (STUArray _l _u n ptr)) count
   | count == 0              = return 0
@@ -87,10 +88,10 @@
 
 -- | Writes an array of 'Word8' to the specified 'Handle'.
 hPutArray
-	:: Handle			-- ^ Handle to write to
-	-> IOUArray Int Word8		-- ^ Array to write from
-	-> Int				-- ^ Number of 'Word8's to write
-	-> IO ()
+        :: Handle                       -- ^ Handle to write to
+        -> IOUArray Int Word8           -- ^ Array to write from
+        -> Int                          -- ^ Number of 'Word8's to write
+        -> IO ()
 
 hPutArray handle (IOUArray (STUArray _l _u n raw)) count
   | count == 0              = return ()
@@ -109,44 +110,56 @@
 -- Internal Utils
 
 illegalBufferSize :: Handle -> String -> Int -> IO a
-illegalBufferSize handle fn sz = 
-	ioException (ioeSetErrorString
-		     (mkIOError InvalidArgument fn (Just handle) Nothing)
-		     ("illegal buffer size " ++ showsPrec 9 (sz::Int) []))
+illegalBufferSize handle fn sz =
+        ioException (ioeSetErrorString
+                     (mkIOError InvalidArgument fn (Just handle) Nothing)
+                     ("illegal buffer size " ++ showsPrec 9 (sz::Int) []))
 
 #else /* !__GLASGOW_HASKELL__ */
 hGetArray :: Handle -> IOUArray Int Word8 -> Int -> IO Int
 hGetArray handle arr count = do
-	bds <- getBounds arr
-	if count < 0 || count > rangeSize bds
-	   then illegalBufferSize handle "hGetArray" count
-	   else get 0
+        bds <- getBounds arr
+        if count < 0 || count > rangeSize bds
+           then illegalBufferSize handle "hGetArray" count
+           else get 0
  where
   get i | i == count = return i
-	| otherwise = do
-		error_or_c <- try (hGetChar handle)
-		case error_or_c of
-		    Left ex
-			| isEOFError ex -> return i
-			| otherwise -> ioError ex
-		    Right c -> do
-			unsafeWrite arr i (fromIntegral (ord c))
-			get (i+1)
+        | otherwise = do
+                error_or_c <- try (hGetChar handle)
+                case error_or_c of
+                    Left ex
+                        | isEOFError ex -> return i
+                        | otherwise -> ioError ex
+                    Right c -> do
+                        unsafeWrite arr i (fromIntegral (ord c))
+                        get (i+1)
 
 hPutArray :: Handle -> IOUArray Int Word8 -> Int -> IO ()
 hPutArray handle arr count = do
-	bds <- getBounds arr
-	if count < 0 || count > rangeSize bds
-	   then illegalBufferSize handle "hPutArray" count
-	   else put 0
+        bds <- getBounds arr
+        if count < 0 || count > rangeSize bds
+           then illegalBufferSize handle "hPutArray" count
+           else put 0
  where
   put i | i == count = return ()
-	| otherwise = do
-		w <- unsafeRead arr i
-		hPutChar handle (chr (fromIntegral w))
-		put (i+1)
+        | otherwise = do
+                w <- unsafeRead arr i
+                hPutChar handle (chr (fromIntegral w))
+                put (i+1)
 
 illegalBufferSize :: Handle -> String -> Int -> IO a
 illegalBufferSize _ fn sz = ioError $
-	userError (fn ++ ": illegal buffer size " ++ showsPrec 9 (sz::Int) [])
+        userError (fn ++ ": illegal buffer size " ++ showsPrec 9 (sz::Int) [])
 #endif /* !__GLASGOW_HASKELL__ */
+
+
+{-# DEPRECATED castIOUArray
+              "Please import from Data.Array.Unsafe instead; This will be removed in the next release"
+ #-}
+-- | Casts an 'IOUArray' with one element type into one with a
+-- different element type.  All the elements of the resulting array
+-- are undefined (unless you know what you\'re doing...).
+{-# INLINE castIOUArray #-}
+castIOUArray :: IOUArray i a -> IO (IOUArray i b)
+castIOUArray = U.castIOUArray
+
diff --git a/Data/Array/IO/Internals.hs b/Data/Array/IO/Internals.hs
--- a/Data/Array/IO/Internals.hs
+++ b/Data/Array/IO/Internals.hs
@@ -1,10 +1,11 @@
+{-# OPTIONS_HADDOCK hide #-}
 {-# OPTIONS_GHC -#include "HsBase.h" #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Array.IO.Internal
 -- 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.Base)
@@ -15,28 +16,29 @@
 
 -- #hide
 module Data.Array.IO.Internals (
-   IOArray(..),		-- instance of: Eq, Typeable
-   IOUArray(..),	-- instance of: Eq, Typeable
-   castIOUArray,	-- :: IOUArray ix a -> IO (IOUArray ix b)
+    IOArray(..),         -- instance of: Eq, Typeable
+    IOUArray(..),        -- instance of: Eq, Typeable
+    castIOUArray,        -- :: IOUArray ix a -> IO (IOUArray ix b)
 #ifdef __GLASGOW_HASKELL__
-   unsafeThawIOUArray,
+    unsafeThawIOUArray,
 #endif
- ) where
+  ) where
 
 import Data.Int
 import Data.Word
 import Data.Typeable
 
+import Control.Monad.ST         ( RealWorld, stToIO )
+import Foreign.Ptr              ( Ptr, FunPtr )
+import Foreign.StablePtr        ( StablePtr )
+
+import Data.Ix
+import Data.Array.Base
+
 #ifdef __HUGS__
 import Hugs.IOArray
 #endif
 
-import Control.Monad.ST		( RealWorld, stToIO )
-import Foreign.Ptr		( Ptr, FunPtr )
-import Foreign.StablePtr	( StablePtr )
-import Data.Array.Base
-import Data.Ix
-
 #ifdef __GLASGOW_HASKELL__
 #if __GLASGOW_HASKELL__ >= 611
 import GHC.IOArray (IOArray(..))
@@ -414,3 +416,4 @@
 "freeze/IOUArray" freeze = freezeIOUArray
     #-}
 #endif /* __GLASGOW_HASKELL__ */
+
diff --git a/Data/Array/IO/Safe.hs b/Data/Array/IO/Safe.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/IO/Safe.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE Trustworthy #-}
+{-# OPTIONS_GHC -#include "HsBase.h" #-}
+{-# OPTIONS_GHC -w #-} --tmp
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Array.IO.Safe
+-- 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 IO monad.
+-- .
+-- Safe API only of "Data.Array.IO".
+--
+-----------------------------------------------------------------------------
+
+module Data.Array.IO.Safe (
+    -- * @IO@ arrays with boxed elements
+    IOArray,             -- instance of: Eq, Typeable
+
+    -- * @IO@ arrays with unboxed elements
+    IOUArray,            -- instance of: Eq, Typeable
+
+    -- * Overloaded mutable array interface
+    module Data.Array.MArray.Safe,
+
+    -- * Doing I\/O with @IOUArray@s
+    hGetArray,           -- :: Handle -> IOUArray Int Word8 -> Int -> IO Int
+    hPutArray,           -- :: Handle -> IOUArray Int Word8 -> Int -> IO ()
+  ) where
+
+import Data.Array.IO
+import Data.Array.MArray.Safe
diff --git a/Data/Array/MArray.hs b/Data/Array/MArray.hs
--- a/Data/Array/MArray.hs
+++ b/Data/Array/MArray.hs
@@ -3,18 +3,18 @@
 -- Module      :  Data.Array.MArray
 -- 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.Base)
 --
 -- An overloaded interface to mutable arrays.  For array types which can be
--- used with this interface, see "Data.Array.IO", "Data.Array.ST", 
+-- used with this interface, see "Data.Array.IO", "Data.Array.ST",
 -- and "Data.Array.Storable".
 --
 -----------------------------------------------------------------------------
 
-module Data.Array.MArray ( 
+module Data.Array.MArray (
     -- * Class of mutable array types
     MArray,       -- :: (* -> * -> *) -> * -> (* -> *) -> class
 
@@ -47,7 +47,81 @@
   ) where
 
 import Data.Ix
+import Data.Array.Base hiding ( unsafeFreeze, unsafeThaw )
+import qualified Data.Array.Base as U ( unsafeFreeze, unsafeThaw )
 #ifdef __HADDOCK__
 import Data.Array.IArray
 #endif
-import Data.Array.Base
+
+{-# DEPRECATED unsafeFreeze, unsafeThaw
+              "Please import from Data.Array.Unsafe instead; This will be removed in the next release"
+ #-}
+
+{- |
+   Converts an mutable array into an immutable array.  The
+   implementation may either simply cast the array from
+   one type to the other without copying the array, or it
+   may take a full copy of the array.
+
+   Note that because the array is possibly not copied, any subsequent
+   modifications made to the mutable version of the array may be
+   shared with the immutable version.  It is safe to use, therefore, if
+   the mutable version is never modified after the freeze operation.
+
+   The non-copying implementation is supported between certain pairs
+   of array types only; one constraint is that the array types must
+   have identical representations.  In GHC, The following pairs of
+   array types have a non-copying O(1) implementation of
+   'unsafeFreeze'.  Because the optimised versions are enabled by
+   specialisations, you will need to compile with optimisation (-O) to
+   get them.
+
+     * 'Data.Array.IO.IOUArray' -> 'Data.Array.Unboxed.UArray'
+
+     * 'Data.Array.ST.STUArray' -> 'Data.Array.Unboxed.UArray'
+
+     * 'Data.Array.IO.IOArray' -> 'Data.Array.Array'
+
+     * 'Data.Array.ST.STArray' -> 'Data.Array.Array'
+-}
+{-# INLINE unsafeFreeze #-}
+unsafeFreeze :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e)
+unsafeFreeze = U.unsafeFreeze
+
+{- |
+   Converts an immutable array into a mutable array.  The
+   implementation may either simply cast the array from
+   one type to the other without copying the array, or it
+   may take a full copy of the array.
+
+   Note that because the array is possibly not copied, any subsequent
+   modifications made to the mutable version of the array may be
+   shared with the immutable version.  It is only safe to use,
+   therefore, if the immutable array is never referenced again in this
+   thread, and there is no possibility that it can be also referenced
+   in another thread.  If you use an unsafeThaw/write/unsafeFreeze
+   sequence in a multi-threaded setting, then you must ensure that
+   this sequence is atomic with respect to other threads, or a garbage
+   collector crash may result (because the write may be writing to a
+   frozen array).
+
+   The non-copying implementation is supported between certain pairs
+   of array types only; one constraint is that the array types must
+   have identical representations.  In GHC, The following pairs of
+   array types have a non-copying O(1) implementation of
+   'unsafeThaw'.  Because the optimised versions are enabled by
+   specialisations, you will need to compile with optimisation (-O) to
+   get them.
+
+     * 'Data.Array.Unboxed.UArray' -> 'Data.Array.IO.IOUArray'
+
+     * 'Data.Array.Unboxed.UArray' -> 'Data.Array.ST.STUArray'
+
+     * 'Data.Array.Array'  -> 'Data.Array.IO.IOArray'
+
+     * 'Data.Array.Array'  -> 'Data.Array.ST.STArray'
+-}
+{-# INLINE unsafeThaw #-}
+unsafeThaw :: (Ix i, IArray a e, MArray b e m) => a i e -> m (b i e)
+unsafeThaw = U.unsafeThaw
+
diff --git a/Data/Array/MArray/Safe.hs b/Data/Array/MArray/Safe.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/MArray/Safe.hs
@@ -0,0 +1,55 @@
+{-# LANGUAGE Trustworthy #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Array.MArray.Safe
+-- 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.Base)
+--
+-- An overloaded interface to mutable arrays.  For array types which can be
+-- used with this interface, see "Data.Array.IO", "Data.Array.ST",
+-- and "Data.Array.Storable".
+-- .
+-- Safe API only of "Data.Array.MArray".
+--
+-----------------------------------------------------------------------------
+
+module Data.Array.MArray.Safe (
+    -- * Class of mutable array types
+    MArray,       -- :: (* -> * -> *) -> * -> (* -> *) -> class
+
+    -- * The @Ix@ class and operations
+    module Data.Ix,
+
+    -- * Constructing mutable arrays
+    newArray,     -- :: (MArray a e m, Ix i) => (i,i) -> e -> m (a i e)
+    newArray_,    -- :: (MArray a e m, Ix i) => (i,i) -> m (a i e)
+    newListArray, -- :: (MArray a e m, Ix i) => (i,i) -> [e] -> m (a i e)
+
+    -- * Reading and writing mutable arrays
+    readArray,    -- :: (MArray a e m, Ix i) => a i e -> i -> m e
+    writeArray,   -- :: (MArray a e m, Ix i) => a i e -> i -> e -> m ()
+
+    -- * Derived arrays
+    mapArray,     -- :: (MArray a e' m, MArray a e m, Ix i) => (e' -> e) -> a i e' -> m (a i e)
+    mapIndices,   -- :: (MArray a e m, Ix i, Ix j) => (i,i) -> (i -> j) -> a j e -> m (a i e)
+
+    -- * Deconstructing mutable arrays
+    getBounds,    -- :: (MArray a e m, Ix i) => a i e -> m (i,i)
+    getElems,     -- :: (MArray a e m, Ix i) => a i e -> m [e]
+    getAssocs,    -- :: (MArray a e m, Ix i) => a i e -> m [(i, e)]
+
+    -- * Conversions between mutable and immutable arrays
+    freeze,       -- :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e)
+    thaw,         -- :: (Ix i, IArray a e, MArray b e m) => a i e -> m (b i e)
+  ) where
+
+import Data.Ix
+import Data.Array.Base
+#ifdef __HADDOCK__
+import Data.Array.IArray
+#endif
+
diff --git a/Data/Array/ST.hs b/Data/Array/ST.hs
--- a/Data/Array/ST.hs
+++ b/Data/Array/ST.hs
@@ -3,7 +3,7 @@
 -- 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)
@@ -13,31 +13,31 @@
 -----------------------------------------------------------------------------
 
 module Data.Array.ST (
-
    -- * Boxed arrays
-   STArray,		-- instance of: Eq, MArray
+   STArray,             -- instance of: Eq, MArray
    runSTArray,
 
    -- * Unboxed arrays
-   STUArray,		-- instance of: Eq, MArray
+   STUArray,            -- instance of: Eq, MArray
    runSTUArray,
-   castSTUArray,	-- :: STUArray s i a -> ST s (STUArray s i b)
+   castSTUArray,        -- :: STUArray s i a -> ST s (STUArray s i b)
 
    -- * Overloaded mutable array interface
    module Data.Array.MArray,
  ) where
 
+import Data.Array.Base  ( STUArray, UArray, unsafeFreezeSTUArray )
 import Data.Array.MArray
-import Data.Array.Base	( STUArray, castSTUArray, UArray, unsafeFreezeSTUArray )
-import Control.Monad.ST	( ST, runST )
+import qualified Data.Array.Unsafe as U ( castSTUArray )
+import Control.Monad.ST ( ST, runST )
 
 #ifdef __HUGS__
-import Hugs.Array	( Array )
-import Hugs.ST		( STArray, unsafeFreezeSTArray )
+import Hugs.Array       ( Array )
+import Hugs.ST          ( STArray, unsafeFreezeSTArray )
 #endif
 
 #ifdef __GLASGOW_HASKELL__
-import GHC.Arr		( STArray, Array, unsafeFreezeSTArray )
+import GHC.Arr          ( STArray, Array, unsafeFreezeSTArray )
 #endif
 
 -- | A safe way to create and work with a mutable array before returning an
@@ -46,8 +46,8 @@
 -- this wrapper is a safe interface to that function.
 --
 runSTArray :: (Ix i)
-	   => (forall s . ST s (STArray s i e))
-	   -> Array i e
+           => (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
@@ -57,19 +57,31 @@
 -- that function.
 --
 runSTUArray :: (Ix i)
-	   => (forall s . ST s (STUArray s i e))
-	   -> UArray i e
+           => (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
+-- 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).
+
+{-# DEPRECATED castSTUArray
+              "Please import from Data.Array.Unsafe instead; This will be removed in the next release"
+ #-}
+
+-- | Casts an 'STUArray' with one element type into one with a
+-- different element type.  All the elements of the resulting array
+-- are undefined (unless you know what you\'re doing...).
+{-# INLINE castSTUArray #-}
+castSTUArray :: STUArray s ix a -> ST s (STUArray s ix b)
+castSTUArray = U.castSTUArray
+
diff --git a/Data/Array/ST/Safe.hs b/Data/Array/ST/Safe.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/ST/Safe.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE Trustworthy #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Array.ST.Safe
+-- Copyright   :  (c) The University of Glasgow 2011
+-- 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.
+--
+-- Safe API only of "Data.Array.ST".
+--
+-----------------------------------------------------------------------------
+
+module Data.Array.ST.Safe (
+   -- * Boxed arrays
+   STArray,             -- instance of: Eq, MArray
+   runSTArray,
+
+   -- * Unboxed arrays
+   STUArray,            -- instance of: Eq, MArray
+   runSTUArray,
+
+   -- * Overloaded mutable array interface
+   module Data.Array.MArray.Safe,
+ ) where
+
+import Data.Array.ST
+import Data.Array.MArray.Safe
+
diff --git a/Data/Array/Storable.hs b/Data/Array/Storable.hs
--- a/Data/Array/Storable.hs
+++ b/Data/Array/Storable.hs
@@ -3,7 +3,7 @@
 -- Module      :  Data.Array.Storable
 -- 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)
@@ -20,76 +20,39 @@
 -----------------------------------------------------------------------------
 
 module Data.Array.Storable (
-    
     -- * Arrays of 'Storable' things.
     StorableArray, -- data StorableArray index element
-                   --     -- index type must be in class Ix
-                   --     -- element type must be in class Storable
-    
+                   --  + index type must be in class Ix
+                   --  + element type must be in class Storable
+
     -- * Overloaded mutable array interface
     -- | Module "Data.Array.MArray" provides the interface of storable arrays.
     -- They are instances of class 'MArray' (with the 'IO' monad).
     module Data.Array.MArray,
-    
+
     -- * Accessing the pointer to the array contents
-    withStorableArray, -- :: StorableArray i e -> (Ptr e -> IO a) -> IO a
-    
+    withStorableArray,  -- :: StorableArray i e -> (Ptr e -> IO a) -> IO a
+
     touchStorableArray, -- :: StorableArray i e -> IO ()
 
     unsafeForeignPtrToStorableArray
-    )
-    where
+  ) where
 
-import Data.Array.Base
-import Data.Array.MArray
 import Foreign hiding (newArray)
 
--- |The array type
-data StorableArray i e = StorableArray !i !i Int !(ForeignPtr e)
-
-instance Storable e => MArray StorableArray e IO where
-    getBounds (StorableArray l u _ _) = return (l,u)
-
-    getNumElements (StorableArray _l _u n _) = return n
-
-    newArray (l,u) initialValue = do
-        fp <- mallocForeignPtrArray size
-        withForeignPtr fp $ \a ->
-            sequence_ [pokeElemOff a i initialValue | i <- [0..size-1]]
-        return (StorableArray l u size fp)
-        where
-        size = rangeSize (l,u)
-
-    unsafeNewArray_ (l,u) = do
-        let n = rangeSize (l,u)
-        fp <- mallocForeignPtrArray n
-        return (StorableArray l u n fp)
-
-    newArray_ = unsafeNewArray_
-
-    unsafeRead (StorableArray _ _ _ fp) i =
-        withForeignPtr fp $ \a -> peekElemOff a i
-
-    unsafeWrite (StorableArray _ _ _ fp) i e =
-        withForeignPtr fp $ \a -> pokeElemOff a i e
-
--- |The pointer to the array contents is obtained by 'withStorableArray'.
--- The idea is similar to 'ForeignPtr' (used internally here).
--- The pointer should be used only during execution of the 'IO' action
--- retured by the function passed as argument to 'withStorableArray'.
-withStorableArray :: StorableArray i e -> (Ptr e -> IO a) -> IO a
-withStorableArray (StorableArray _ _ _ fp) f = withForeignPtr fp f
+import Data.Array.MArray
+import Data.Array.Storable.Internals hiding ( unsafeForeignPtrToStorableArray )
+import qualified Data.Array.Unsafe as U ( unsafeForeignPtrToStorableArray )
 
--- |If you want to use it afterwards, ensure that you
--- 'touchStorableArray' after the last use of the pointer,
--- so the array is not freed too early.
-touchStorableArray :: StorableArray i e -> IO ()
-touchStorableArray (StorableArray _ _ _ fp) = touchForeignPtr fp
+{-# DEPRECATED unsafeForeignPtrToStorableArray
+              "Please import from Data.Array.Unsafe instead; This will be removed in the next release"
+ #-}
 
 -- |Construct a 'StorableArray' from an arbitrary 'ForeignPtr'.  It is
 -- the caller's responsibility to ensure that the 'ForeignPtr' points to
 -- an area of memory sufficient for the specified bounds.
+{-# INLINE unsafeForeignPtrToStorableArray #-}
 unsafeForeignPtrToStorableArray
    :: Ix i => ForeignPtr e -> (i,i) -> IO (StorableArray i e)
-unsafeForeignPtrToStorableArray p (l,u) =
-   return (StorableArray l u (rangeSize (l,u)) p)
+unsafeForeignPtrToStorableArray = U.unsafeForeignPtrToStorableArray
+
diff --git a/Data/Array/Storable/Internals.hs b/Data/Array/Storable/Internals.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/Storable/Internals.hs
@@ -0,0 +1,77 @@
+{-# OPTIONS_HADDOCK hide #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Array.Storable.Internals
+-- Copyright   :  (c) The University of Glasgow 2011
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  experimental
+-- Portability :  non-portable (uses Data.Array.MArray)
+--
+-- Actual implementation of "Data.Array.Storable".
+--
+-----------------------------------------------------------------------------
+
+-- #hide
+module Data.Array.Storable.Internals (
+    StorableArray(..),
+    withStorableArray,
+    touchStorableArray,
+    unsafeForeignPtrToStorableArray,
+  ) where
+
+import Data.Array.Base
+import Data.Array.MArray
+import Foreign hiding (newArray)
+
+-- |The array type
+data StorableArray i e = StorableArray !i !i Int !(ForeignPtr e)
+
+instance Storable e => MArray StorableArray e IO where
+    getBounds (StorableArray l u _ _) = return (l,u)
+
+    getNumElements (StorableArray _l _u n _) = return n
+
+    newArray (l,u) initialValue = do
+        fp <- mallocForeignPtrArray size
+        withForeignPtr fp $ \a ->
+            sequence_ [pokeElemOff a i initialValue | i <- [0..size-1]]
+        return (StorableArray l u size fp)
+        where
+        size = rangeSize (l,u)
+
+    unsafeNewArray_ (l,u) = do
+        let n = rangeSize (l,u)
+        fp <- mallocForeignPtrArray n
+        return (StorableArray l u n fp)
+
+    newArray_ = unsafeNewArray_
+
+    unsafeRead (StorableArray _ _ _ fp) i =
+        withForeignPtr fp $ \a -> peekElemOff a i
+
+    unsafeWrite (StorableArray _ _ _ fp) i e =
+        withForeignPtr fp $ \a -> pokeElemOff a i e
+
+-- |The pointer to the array contents is obtained by 'withStorableArray'.
+-- The idea is similar to 'ForeignPtr' (used internally here).
+-- The pointer should be used only during execution of the 'IO' action
+-- retured by the function passed as argument to 'withStorableArray'.
+withStorableArray :: StorableArray i e -> (Ptr e -> IO a) -> IO a
+withStorableArray (StorableArray _ _ _ fp) f = withForeignPtr fp f
+
+-- |If you want to use it afterwards, ensure that you
+-- 'touchStorableArray' after the last use of the pointer,
+-- so the array is not freed too early.
+touchStorableArray :: StorableArray i e -> IO ()
+touchStorableArray (StorableArray _ _ _ fp) = touchForeignPtr fp
+
+-- |Construct a 'StorableArray' from an arbitrary 'ForeignPtr'.  It is
+-- the caller's responsibility to ensure that the 'ForeignPtr' points to
+-- an area of memory sufficient for the specified bounds.
+unsafeForeignPtrToStorableArray
+   :: Ix i => ForeignPtr e -> (i,i) -> IO (StorableArray i e)
+unsafeForeignPtrToStorableArray p (l,u) =
+   return (StorableArray l u (rangeSize (l,u)) p)
+
diff --git a/Data/Array/Storable/Safe.hs b/Data/Array/Storable/Safe.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/Storable/Safe.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE Trustworthy #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Array.Storable.Safe
+-- 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)
+--
+-- A storable array is an IO-mutable array which stores its
+-- contents in a contiguous memory block living in the C
+-- heap. Elements are stored according to the class 'Storable'.
+-- You can obtain the pointer to the array contents to manipulate
+-- elements from languages like C.
+--
+-- It is similar to 'Data.Array.IO.IOUArray' but slower.
+-- Its advantage is that it's compatible with C.
+--
+-- Safe API only of "Data.Array.Storable".
+--
+-----------------------------------------------------------------------------
+
+module Data.Array.Storable.Safe (
+    -- * Arrays of 'Storable' things.
+    StorableArray, -- data StorableArray index element
+                   --  + index type must be in class Ix
+                   --  + element type must be in class Storable
+
+    -- * Overloaded mutable array interface
+    -- | Module "Data.Array.MArray" provides the interface of storable arrays.
+    -- They are instances of class 'MArray' (with the 'IO' monad).
+    module Data.Array.MArray.Safe,
+
+    -- * Accessing the pointer to the array contents
+    withStorableArray,  -- :: StorableArray i e -> (Ptr e -> IO a) -> IO a
+
+    touchStorableArray, -- :: StorableArray i e -> IO ()
+  ) where
+
+import Data.Array.MArray.Safe
+import Data.Array.Storable.Internals
+
diff --git a/Data/Array/Unboxed.hs b/Data/Array/Unboxed.hs
--- a/Data/Array/Unboxed.hs
+++ b/Data/Array/Unboxed.hs
@@ -1,9 +1,10 @@
+{-# LANGUAGE Trustworthy #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Array.Unboxed
 -- 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.IArray)
@@ -13,12 +14,13 @@
 -----------------------------------------------------------------------------
 
 module Data.Array.Unboxed (
-   -- * Arrays with unboxed elements
-   UArray,
+    -- * Arrays with unboxed elements
+    UArray,
 
-   -- * The overloaded immutable array interface
-   module Data.Array.IArray,
- ) where
+    -- * The overloaded immutable array interface
+    module Data.Array.IArray,
+  ) where
 
-import Data.Array.IArray
 import Data.Array.Base
+import Data.Array.IArray
+
diff --git a/Data/Array/Unsafe.hs b/Data/Array/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/Unsafe.hs
@@ -0,0 +1,32 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Array.Unsafe
+-- Copyright   :  (c) The University of Glasgow 2011
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  experimental
+-- Portability :  non-portable (uses Data.Array.MArray)
+--
+-- Contains the various unsafe operations that can be performed
+-- on arrays.
+--
+-----------------------------------------------------------------------------
+
+module Data.Array.Unsafe (
+    -- * Unsafe operations
+    castSTUArray,  -- :: STUArray s i a -> ST s (STUArray s i b)
+    castIOUArray,  -- :: IOUArray i a -> IO (IOUArray i b)
+
+    unsafeFreeze,  -- :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e)
+    unsafeThaw,    -- :: (Ix i, IArray a e, MArray b e m) => a i e -> m (b i e)
+
+    unsafeForeignPtrToStorableArray -- :: Ix i => ForeignPtr e -> (i,i)
+                                    --         -> IO (StorableArray i e)
+  ) where
+
+
+import Data.Array.Base ( castSTUArray, unsafeFreeze, unsafeThaw )
+import Data.Array.IO.Internals ( castIOUArray )
+import Data.Array.Storable.Internals ( unsafeForeignPtrToStorableArray )
+
diff --git a/array.cabal b/array.cabal
--- a/array.cabal
+++ b/array.cabal
@@ -1,5 +1,5 @@
 name:       array
-version:    0.3.0.3
+version:    0.4.0.0
 license:    BSD3
 license-file:    LICENSE
 maintainer:    libraries@haskell.org
@@ -28,11 +28,17 @@
       Data.Array.Base
       Data.Array.IArray
       Data.Array.IO
+      Data.Array.IO.Safe
       Data.Array.IO.Internals
       Data.Array.MArray
+      Data.Array.MArray.Safe
       Data.Array.ST
+      Data.Array.ST.Safe
       Data.Array.Storable
+      Data.Array.Storable.Safe
+      Data.Array.Storable.Internals
       Data.Array.Unboxed
+      Data.Array.Unsafe
     extensions:
       MultiParamTypeClasses,
       FlexibleContexts,
