[project @ 2001-02-22 16:10:12 by rrt]
[ghc-hetmet.git] / ghc / lib / std / PrelArr.lhs
index e1d1f2b..7cfb6bd 100644 (file)
+% -----------------------------------------------------------------------------
+% $Id: PrelArr.lhs,v 1.25 2000/08/31 19:57:42 simonpj Exp $
 %
-% (c) The AQUA Project, Glasgow University, 1994-1996
+% (c) The University of Glasgow, 1994-2000
 %
+
 \section[PrelArr]{Module @PrelArr@}
 
 Array implementation, @PrelArr@ exports the basic array
 types and operations.
 
+For byte-arrays see @PrelByteArr@.
+
 \begin{code}
 {-# OPTIONS -fno-implicit-prelude #-}
 
 module PrelArr where
 
 import {-# SOURCE #-} PrelErr ( error )
-import Ix
-import PrelList (foldl)
+import PrelEnum
+import PrelNum
 import PrelST
 import PrelBase
-import PrelCCall
-import PrelAddr
-import PrelGHC
+import PrelShow
 
 infixl 9  !, //
+
+default ()
 \end{code}
 
+
+%*********************************************************
+%*                                                     *
+\subsection{The @Ix@ class}
+%*                                                     *
+%*********************************************************
+
 \begin{code}
-{-# SPECIALISE array :: (Int,Int) -> [(Int,b)] -> Array Int b #-}
-array                :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
+class  (Ord a) => Ix a  where
+    range              :: (a,a) -> [a]
+    index, unsafeIndex :: (a,a) -> a -> Int
+    inRange            :: (a,a) -> a -> Bool
+
+       -- Must specify one of index, unsafeIndex
+    index b i | inRange b i = unsafeIndex b i
+             | otherwise   = error "Error in array index"
+    unsafeIndex b i = index b i
+\end{code}
 
-{-# SPECIALISE (!) :: Array Int b -> Int -> b #-}
-(!)                  :: (Ix a) => Array a b -> a -> b
 
-{-# SPECIALISE bounds :: Array Int b -> (Int,Int) #-}
-bounds               :: (Ix a) => Array a b -> (a,a)
+%*********************************************************
+%*                                                     *
+\subsection{Instances of @Ix@}
+%*                                                     *
+%*********************************************************
 
-{-# SPECIALISE (//) :: Array Int b -> [(Int,b)] -> Array Int b #-}
-(//)                 :: (Ix a) => Array a b -> [(a,b)] -> Array a b
+\begin{code}
+-- abstract these errors from the relevant index functions so that
+-- the guts of the function will be small enough to inline.
 
-{-# SPECIALISE accum  :: (b -> c -> b) -> Array Int b -> [(Int,c)] -> Array Int b #-}
-accum                :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
+{-# NOINLINE indexError #-}
+indexError :: Show a => (a,a) -> a -> String -> b
+indexError rng i tp
+  = error (showString "Ix{" . showString tp . showString "}.index: Index " .
+           showParen True (showsPrec 0 i) .
+          showString " out of range " $
+          showParen True (showsPrec 0 rng) "")
 
-{-# SPECIALISE accumArray :: (b -> c -> b) -> b -> (Int,Int) -> [(Int,c)] -> Array Int b #-}
-accumArray           :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
+----------------------------------------------------------------------
+instance  Ix Char  where
+    {-# INLINE range #-}
+    range (m,n) = [m..n]
+
+    {-# INLINE unsafeIndex #-}
+    unsafeIndex (m,_n) i = fromEnum i - fromEnum m
+
+    index b i | inRange b i =  unsafeIndex b i
+             | otherwise   =  indexError b i "Char"
+
+    inRange (m,n) i    =  m <= i && i <= n
+
+----------------------------------------------------------------------
+instance  Ix Int  where
+    {-# INLINE range #-}
+       -- The INLINE stops the build in the RHS from getting inlined,
+       -- so that callers can fuse with the result of range
+    range (m,n) = [m..n]
+
+    {-# INLINE unsafeIndex #-}
+    unsafeIndex (m,_n) i = i - m
+
+    index b i | inRange b i =  unsafeIndex b i
+             | otherwise   =  indexError b i "Int"
+
+    {-# INLINE inRange #-}
+    inRange (I# m,I# n) (I# i) =  m <=# i && i <=# n
+
+----------------------------------------------------------------------
+instance  Ix Integer  where
+    {-# INLINE range #-}
+    range (m,n) = [m..n]
+
+    {-# INLINE unsafeIndex #-}
+    unsafeIndex (m,_n) i   = fromInteger (i - m)
+
+    index b i | inRange b i =  unsafeIndex b i
+             | otherwise   =  indexError b i "Integer"
+
+    inRange (m,n) i    =  m <= i && i <= n
+
+
+----------------------------------------------------------------------
+instance Ix Bool where -- as derived
+    {-# INLINE range #-}
+    range (m,n) = [m..n]
+
+    {-# INLINE unsafeIndex #-}
+    unsafeIndex (l,_) i = fromEnum i - fromEnum l
+
+    index b i | inRange b i =  unsafeIndex b i
+             | otherwise   =  indexError b i "Bool"
+
+    inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
+
+----------------------------------------------------------------------
+instance Ix Ordering where -- as derived
+    {-# INLINE range #-}
+    range (m,n) = [m..n]
+
+    {-# INLINE unsafeIndex #-}
+    unsafeIndex (l,_) i = fromEnum i - fromEnum l
+
+    index b i | inRange b i =  unsafeIndex b i
+             | otherwise   =  indexError b i "Ordering"
+
+    inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u
+
+----------------------------------------------------------------------
+instance Ix () where
+    {-# INLINE range #-}
+    range   ((), ())    = [()]
+    {-# INLINE unsafeIndex #-}
+    unsafeIndex   ((), ()) () = 0
+    {-# INLINE inRange #-}
+    inRange ((), ()) () = True
+    {-# INLINE index #-}
+    index b i = unsafeIndex b i
+
+
+----------------------------------------------------------------------
+instance (Ix a, Ix b) => Ix (a, b) where -- as derived
+    {-# SPECIALISE instance Ix (Int,Int) #-}
+
+    {- INLINE range #-}
+    range ((l1,l2),(u1,u2)) =
+      [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ]
+
+    {- INLINE unsafeIndex #-}
+    unsafeIndex ((l1,l2),(u1,u2)) (i1,i2) =
+      unsafeIndex (l1,u1) i1 * unsafeRangeSize (l2,u2) + unsafeIndex (l2,u2) i2
+
+    {- INLINE inRange #-}
+    inRange ((l1,l2),(u1,u2)) (i1,i2) =
+      inRange (l1,u1) i1 && inRange (l2,u2) i2
+
+    -- Default method for index
+
+----------------------------------------------------------------------
+instance  (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3)  where
+    {-# SPECIALISE instance Ix (Int,Int,Int) #-}
+
+    range ((l1,l2,l3),(u1,u2,u3)) =
+        [(i1,i2,i3) | i1 <- range (l1,u1),
+                      i2 <- range (l2,u2),
+                      i3 <- range (l3,u3)]
+
+    unsafeIndex ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
+      unsafeIndex (l3,u3) i3 + unsafeRangeSize (l3,u3) * (
+      unsafeIndex (l2,u2) i2 + unsafeRangeSize (l2,u2) * (
+      unsafeIndex (l1,u1) i1))
+
+    inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) =
+      inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
+      inRange (l3,u3) i3
+
+    -- Default method for index
+
+----------------------------------------------------------------------
+instance  (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4)  where
+    range ((l1,l2,l3,l4),(u1,u2,u3,u4)) =
+      [(i1,i2,i3,i4) | i1 <- range (l1,u1),
+                       i2 <- range (l2,u2),
+                       i3 <- range (l3,u3),
+                       i4 <- range (l4,u4)]
+
+    unsafeIndex ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
+      unsafeIndex (l4,u4) i4 + unsafeRangeSize (l4,u4) * (
+      unsafeIndex (l3,u3) i3 + unsafeRangeSize (l3,u3) * (
+      unsafeIndex (l2,u2) i2 + unsafeRangeSize (l2,u2) * (
+      unsafeIndex (l1,u1) i1)))
+
+    inRange ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) =
+      inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
+      inRange (l3,u3) i3 && inRange (l4,u4) i4
+
+    -- Default method for index
+
+instance  (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5)  where
+    range ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) =
+      [(i1,i2,i3,i4,i5) | i1 <- range (l1,u1),
+                          i2 <- range (l2,u2),
+                          i3 <- range (l3,u3),
+                          i4 <- range (l4,u4),
+                          i5 <- range (l5,u5)]
+
+    unsafeIndex ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
+      unsafeIndex (l5,u5) i5 + unsafeRangeSize (l5,u5) * (
+      unsafeIndex (l4,u4) i4 + unsafeRangeSize (l4,u4) * (
+      unsafeIndex (l3,u3) i3 + unsafeRangeSize (l3,u3) * (
+      unsafeIndex (l2,u2) i2 + unsafeRangeSize (l2,u2) * (
+      unsafeIndex (l1,u1) i1))))
+
+    inRange ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) =
+      inRange (l1,u1) i1 && inRange (l2,u2) i2 &&
+      inRange (l3,u3) i3 && inRange (l4,u4) i4 && 
+      inRange (l5,u5) i5
+
+    -- Default method for index
+\end{code}
+
+
+%********************************************************
+%*                                                     *
+\subsection{Size of @Ix@ interval}
+%*                                                     *
+%********************************************************
+
+The @rangeSize@ operator returns the number of elements
+in the range for an @Ix@ pair.
+
+\begin{code}
+{-# SPECIALISE unsafeRangeSize :: (Int,Int) -> Int #-}
+{-# SPECIALISE unsafeRangeSize :: ((Int,Int),(Int,Int)) -> Int #-}
+unsafeRangeSize :: (Ix a) => (a,a) -> Int
+unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
+
+{-# SPECIALISE rangeSize :: (Int,Int) -> Int #-}
+{-# SPECIALISE rangeSize :: ((Int,Int),(Int,Int)) -> Int #-}
+rangeSize :: (Ix a) => (a,a) -> Int
+rangeSize b@(_l,h) | inRange b h = unsafeIndex b h + 1
+                  | otherwise   = 0
+
+-- Note that the following is NOT right
+--     rangeSize (l,h) | l <= h    = index b h + 1
+--                     | otherwise = 0
+--
+-- Because it might be the case that l<h, but the range
+-- is nevertheless empty.  Consider
+--     ((1,2),(2,1))
+-- Here l<h, but the second index ranges from 2..1 and
+-- hence is empty
 \end{code}
 
 
+
 %*********************************************************
 %*                                                     *
 \subsection{The @Array@ types}
@@ -53,28 +272,26 @@ accumArray       :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a
 \begin{code}
 type IPr = (Int, Int)
 
-data Ix ix => Array ix elt             = Array            ix ix (Array# elt)
-data Ix ix => ByteArray ix             = ByteArray        ix ix ByteArray#
-data Ix ix => MutableArray     s ix elt = MutableArray     ix ix (MutableArray# s elt)
-data Ix ix => MutableByteArray s ix     = MutableByteArray ix ix (MutableByteArray# s)
+data Ix ix => Array     ix elt = Array   ix ix (Array# elt)
+data Ix ix => STArray s ix elt = STArray ix ix (MutableArray# s elt)
+
+-- Mutterings about dependent types... ignore!
+-- Array :: ix -> ix -> Array# elt -> Array
+-- Array :: forall { l::int, h::int, l<=h } Int(l) -> Int(h) -> Array#(h-l+1) -> Array(l,h)
+-- Array :: forall { l1,l2::int, h1,h2::int, l1<=h1+1,l2<=h2+1 } 
+--                (Int(l1),Int(l2)) -> (Int(h1),Int(h2)) -> Array#((h1-l1+1)*(h2-l2+1)) -> Array(l1,h1,l2,h2)
 
-instance CCallable (MutableByteArray s ix)
-instance CCallable (ByteArray ix)
 
-data MutableVar s a = MutableVar (MutVar# s a)
+data STRef s a = STRef (MutVar# s a)
 
-instance Eq (MutableVar s a) where
-       MutableVar v1# == MutableVar v2#
+instance Eq (STRef s a) where
+       STRef v1# == STRef v2#
                = sameMutVar# v1# v2#
 
 -- just pointer equality on arrays:
-instance Eq (MutableArray s ix elt) where
-       MutableArray _ _ arr1# == MutableArray _ _ arr2# 
+instance Eq (STArray s ix elt) where
+       STArray _ _ arr1# == STArray _ _ arr2# 
                = sameMutableArray# arr1# arr2#
-
-instance Eq (MutableByteArray s ix) where
-       MutableByteArray _ _ arr1# == MutableByteArray _ _ arr2#
-               = sameMutableByteArray# arr1# arr2#
 \end{code}
 
 %*********************************************************
@@ -84,17 +301,17 @@ instance Eq (MutableByteArray s ix) where
 %*********************************************************
 
 \begin{code}
-newVar   :: a -> ST s (MutableVar s a)
-readVar  :: MutableVar s a -> ST s a
-writeVar :: MutableVar s a -> a -> ST s ()
+newSTRef   :: a -> ST s (STRef s a)
+readSTRef  :: STRef s a -> ST s a
+writeSTRef :: STRef s a -> a -> ST s ()
 
-newVar init = ST $ \ s# ->
+newSTRef init = ST $ \ s# ->
     case (newMutVar# init s#)     of { (# s2#, var# #) ->
-    (# s2#, MutableVar var# #) }
+    (# s2#, STRef var# #) }
 
-readVar (MutableVar var#) = ST $ \ s# -> readMutVar# var# s#
+readSTRef (STRef var#) = ST $ \ s# -> readMutVar# var# s#
 
-writeVar (MutableVar var#) val = ST $ \ s# ->
+writeSTRef (STRef var#) val = ST $ \ s# ->
     case writeMutVar# var# val s# of { s2# ->
     (# s2#, () #) }
 \end{code}
@@ -108,14 +325,33 @@ writeVar (MutableVar var#) val = ST $ \ s# ->
 "array", "!" and "bounds" are basic; the rest can be defined in terms of them
 
 \begin{code}
+bounds               :: (Ix a) => Array a b -> (a,a)
+{-# INLINE bounds #-}
 bounds (Array l u _)  = (l,u)
 
+assocs               :: (Ix a) => Array a b -> [(a,b)]
+{-# INLINE assocs #-}  -- Want to fuse the list comprehension
+assocs a              =  [(i, a!i) | i <- indices a]
+
+indices                      :: (Ix a) => Array a b -> [a]
+{-# INLINE indices #-}
+indices                      =  range . bounds
+
+{-# SPECIALISE amap :: (b -> c) -> Array Int b -> Array Int c #-}
+amap                 :: (Ix a) => (b -> c) -> Array a b -> Array a c
+amap f a              =  array b [(i, f (a!i)) | i <- range b]
+                         where b = bounds a
+
+{-# SPECIALISE (!) :: Array Int b -> Int -> b #-}
+(!)                  :: (Ix a) => Array a b -> a -> b
 (Array l u arr#) ! i
   = let n# = case (index (l,u) i) of { I# x -> x } -- index fails if out of range
     in
     case (indexArray# arr# n#) of
       (# v #) -> v
 
+
+array                :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
 {-# INLINE array #-}
 array ixs ivs 
   = case rangeSize ixs                         of { I# n ->
@@ -146,24 +382,25 @@ arrEleBottom = error "(Array.!): undefined array element"
 -- These also go better with magic: (//), accum, accumArray
 -- *** NB *** We INLINE them all so that their foldr's get to the call site
 
+(//)                 :: (Ix a) => Array a b -> [(a,b)] -> Array a b
 {-# INLINE (//) #-}
 old_array // ivs
   = runST (do
        -- copy the old array:
-       arr <- thawArray old_array
+       arr <- thawSTArray old_array
        -- now write the new elements into the new array:
        fill_it_in arr ivs
-       freezeArray arr
+       freezeSTArray arr
     )
 
-fill_it_in :: Ix ix => MutableArray s ix elt -> [(ix, elt)] -> ST s ()
+fill_it_in :: Ix ix => STArray s ix elt -> [(ix, elt)] -> ST s ()
 {-# INLINE fill_it_in #-}
 fill_it_in arr lst = foldr (fill_one_in arr) (return ()) lst
         -- **** STRICT **** (but that's OK...)
 
-fill_one_in arr (i, v) rst = writeArray arr i v >> rst
+fill_one_in arr (i, v) rst = writeSTArray arr i v >> rst
 
-zap_with_f :: Ix ix => (elt -> elt2 -> elt) -> MutableArray s ix elt -> [(ix,elt2)] -> ST s ()
+zap_with_f :: Ix ix => (elt -> elt2 -> elt) -> STArray s ix elt -> [(ix,elt2)] -> ST s ()
 -- zap_with_f: reads an elem out first, then uses "f" on that and the new value
 {-# INLINE zap_with_f #-}
 
@@ -171,38 +408,77 @@ zap_with_f f arr lst
   = foldr (zap_one f arr) (return ()) lst
 
 zap_one f arr (i, new_v) rst = do
-        old_v <- readArray arr i
-       writeArray arr i (f old_v new_v)
+        old_v <- readSTArray arr i
+       writeSTArray arr i (f old_v new_v)
        rst
 
+accum                :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
 {-# INLINE accum #-}
 accum f old_array ivs
   = runST (do
        -- copy the old array:
-       arr <- thawArray old_array
+       arr <- thawSTArray old_array
        -- now zap the elements in question with "f":
        zap_with_f f arr ivs
-       freezeArray arr
+       freezeSTArray arr
     )
 
+
+accumArray           :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
 {-# INLINE accumArray #-}
 accumArray f zero ixs ivs
   = runST (do
-       arr <- newArray ixs zero
+       arr <- newSTArray ixs zero
        zap_with_f f arr ivs
-       freezeArray arr
+       freezeSTArray arr
     )
 \end{code}
 
 
 %*********************************************************
 %*                                                     *
+\subsection{Array instances}
+%*                                                     *
+%*********************************************************
+
+
+\begin{code}
+instance Ix a => Functor (Array a) where
+  fmap = amap
+
+instance  (Ix a, Eq b)  => Eq (Array a b)  where
+    a == a'            =  assocs a == assocs a'
+    a /= a'            =  assocs a /= assocs a'
+
+instance  (Ix a, Ord b) => Ord (Array a b)  where
+    compare a b = compare (assocs a) (assocs b)
+
+instance  (Ix a, Show a, Show b) => Show (Array a b)  where
+    showsPrec p a = showParen (p > 9) (
+                   showString "array " .
+                   shows (bounds a) . showChar ' ' .
+                   shows (assocs a)                  )
+    showList = showList__ (showsPrec 0)
+
+{-
+instance  (Ix a, Read a, Read b) => Read (Array a b)  where
+    readsPrec p = readParen (p > 9)
+          (\r -> [(array b as, u) | ("array",s) <- lex r,
+                                    (b,t)       <- reads s,
+                                    (as,u)      <- reads t   ])
+    readList = readList__ (readsPrec 0)
+-}
+\end{code}
+
+
+%*********************************************************
+%*                                                     *
 \subsection{Operations on mutable arrays}
 %*                                                     *
 %*********************************************************
 
 Idle ADR question: What's the tradeoff here between flattening these
-datatypes into @MutableArray ix ix (MutableArray# s elt)@ and using
+datatypes into @STArray ix ix (MutableArray# s elt)@ and using
 it as is?  As I see it, the former uses slightly less heap and
 provides faster access to the individual parts of the bounds while the
 code used has the benefit of providing a ready-made @(lo, hi)@ pair as
@@ -215,209 +491,41 @@ it frequently. Now we've got the overloading specialiser things
 might be different, though.
 
 \begin{code}
-newArray :: Ix ix => (ix,ix) -> elt -> ST s (MutableArray s ix elt)
-newCharArray, newIntArray, newWordArray, newAddrArray, newFloatArray, newDoubleArray
-        :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix) 
+newSTArray :: Ix ix => (ix,ix) -> elt -> ST s (STArray s ix elt)
 
-{-# SPECIALIZE newArray      :: IPr       -> elt -> ST s (MutableArray s Int elt),
-                               (IPr,IPr) -> elt -> ST s (MutableArray s IPr elt)
+{-# SPECIALIZE newSTArray :: IPr       -> elt -> ST s (STArray s Int elt),
+                            (IPr,IPr) -> elt -> ST s (STArray s IPr elt)
   #-}
-{-# SPECIALIZE newCharArray   :: IPr -> ST s (MutableByteArray s Int) #-}
-{-# SPECIALIZE newIntArray    :: IPr -> ST s (MutableByteArray s Int) #-}
-{-# SPECIALIZE newWordArray   :: IPr -> ST s (MutableByteArray s Int) #-}
-{-# SPECIALIZE newAddrArray   :: IPr -> ST s (MutableByteArray s Int) #-}
-{-# SPECIALIZE newFloatArray  :: IPr -> ST s (MutableByteArray s Int) #-}
-{-# SPECIALIZE newDoubleArray :: IPr -> ST s (MutableByteArray s Int) #-}
-
-newArray (l,u) init = ST $ \ s# ->
+newSTArray (l,u) init = ST $ \ s# ->
     case rangeSize (l,u)          of { I# n# ->
     case (newArray# n# init s#)   of { (# s2#, arr# #) ->
-    (# s2#, MutableArray l u arr# #) }}
-
-newCharArray (l,u) = ST $ \ s# ->
-    case rangeSize (l,u)          of { I# n# ->
-    case (newCharArray# n# s#)   of { (# s2#, barr# #) ->
-    (# s2#, MutableByteArray l u barr# #) }}
-
-newIntArray (l,u) = ST $ \ s# ->
-    case rangeSize (l,u)          of { I# n# ->
-    case (newIntArray# n# s#)    of { (# s2#, barr# #) ->
-    (# s2#, MutableByteArray l u barr# #) }}
-
-newWordArray (l,u) = ST $ \ s# ->
-    case rangeSize (l,u)          of { I# n# ->
-    case (newWordArray# n# s#)   of { (# s2#, barr# #) ->
-    (# s2#, MutableByteArray l u barr# #) }}
-
-newAddrArray (l,u) = ST $ \ s# ->
-    case rangeSize (l,u)          of { I# n# ->
-    case (newAddrArray# n# s#)   of { (# s2#, barr# #) ->
-    (# s2#, MutableByteArray l u barr# #) }}
-
-newFloatArray (l,u) = ST $ \ s# ->
-    case rangeSize (l,u)          of { I# n# ->
-    case (newFloatArray# n# s#)          of { (# s2#, barr# #) ->
-    (# s2#, MutableByteArray l u barr# #) }}
-
-newDoubleArray (l,u) = ST $ \ s# ->
-    case rangeSize (l,u)          of { I# n# ->
-    case (newDoubleArray# n# s#)  of { (# s2#, barr# #) ->
-    (# s2#, MutableByteArray l u barr# #) }}
-
-boundsOfArray     :: Ix ix => MutableArray s ix elt -> (ix, ix)  
-
-{-# SPECIALIZE boundsOfArray     :: MutableArray s Int elt -> IPr #-}
+    (# s2#, STArray l u arr# #) }}
 
-boundsOfArray     (MutableArray     l u _) = (l,u)
 
-readArray      :: Ix ix => MutableArray s ix elt -> ix -> ST s elt 
 
-readCharArray   :: Ix ix => MutableByteArray s ix -> ix -> ST s Char 
-readIntArray    :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
-readWordArray   :: Ix ix => MutableByteArray s ix -> ix -> ST s Word
-readAddrArray   :: Ix ix => MutableByteArray s ix -> ix -> ST s Addr
-readFloatArray  :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
-readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
+boundsSTArray     :: Ix ix => STArray s ix elt -> (ix, ix)  
+{-# SPECIALIZE boundsSTArray :: STArray s Int elt -> IPr #-}
+boundsSTArray     (STArray     l u _) = (l,u)
 
-{-# SPECIALIZE readArray       :: MutableArray s Int elt -> Int -> ST s elt,
-                                 MutableArray s IPr elt -> IPr -> ST s elt
+readSTArray    :: Ix ix => STArray s ix elt -> ix -> ST s elt 
+{-# SPECIALIZE readSTArray :: STArray s Int elt -> Int -> ST s elt,
+                             STArray s IPr elt -> IPr -> ST s elt
   #-}
-{-# SPECIALIZE readCharArray   :: MutableByteArray s Int -> Int -> ST s Char #-}
-{-# SPECIALIZE readIntArray    :: MutableByteArray s Int -> Int -> ST s Int #-}
-{-# SPECIALIZE readAddrArray   :: MutableByteArray s Int -> Int -> ST s Addr #-}
---NO:{-# SPECIALIZE readFloatArray  :: MutableByteArray s Int -> Int -> ST s Float #-}
-{-# SPECIALIZE readDoubleArray :: MutableByteArray s Int -> Int -> ST s Double #-}
 
-readArray (MutableArray l u arr#) n = ST $ \ s# ->
+readSTArray (STArray l u arr#) n = ST $ \ s# ->
     case (index (l,u) n)               of { I# n# ->
     case readArray# arr# n# s#         of { (# s2#, r #) ->
     (# s2#, r #) }}
 
-readCharArray (MutableByteArray l u barr#) n = ST $ \ s# ->
-    case (index (l,u) n)               of { I# n# ->
-    case readCharArray# barr# n# s#    of { (# s2#, r# #) ->
-    (# s2#, C# r# #) }}
-
-readIntArray (MutableByteArray l u barr#) n = ST $ \ s# ->
-    case (index (l,u) n)               of { I# n# ->
-    case readIntArray# barr# n# s#     of { (# s2#, r# #) ->
-    (# s2#, I# r# #) }}
-
-readWordArray (MutableByteArray l u barr#) n = ST $ \ s# ->
-    case (index (l,u) n)               of { I# n# ->
-    case readWordArray# barr# n# s#    of { (# s2#, r# #) ->
-    (# s2#, W# r# #) }}
-
-readAddrArray (MutableByteArray l u barr#) n = ST $ \ s# ->
-    case (index (l,u) n)               of { I# n# ->
-    case readAddrArray# barr# n# s#    of { (# s2#, r# #) ->
-    (# s2#, A# r# #) }}
-
-readFloatArray (MutableByteArray l u barr#) n = ST $ \ s# ->
-    case (index (l,u) n)               of { I# n# ->
-    case readFloatArray# barr# n# s#   of { (# s2#, r# #) ->
-    (# s2#, F# r# #) }}
-
-readDoubleArray (MutableByteArray l u barr#) n = ST $ \ s# ->
-    case (index (l,u) n)               of { I# n# ->
-    case readDoubleArray# barr# n# s#  of { (# s2#, r# #) ->
-    (# s2#, D# r# #) }}
-
---Indexing of ordinary @Arrays@ is standard Haskell and isn't defined here.
-indexCharArray   :: Ix ix => ByteArray ix -> ix -> Char 
-indexIntArray    :: Ix ix => ByteArray ix -> ix -> Int
-indexWordArray   :: Ix ix => ByteArray ix -> ix -> Word
-indexAddrArray   :: Ix ix => ByteArray ix -> ix -> Addr
-indexFloatArray  :: Ix ix => ByteArray ix -> ix -> Float
-indexDoubleArray :: Ix ix => ByteArray ix -> ix -> Double
-
-{-# SPECIALIZE indexCharArray   :: ByteArray Int -> Int -> Char #-}
-{-# SPECIALIZE indexIntArray    :: ByteArray Int -> Int -> Int #-}
-{-# SPECIALIZE indexAddrArray   :: ByteArray Int -> Int -> Addr #-}
---NO:{-# SPECIALIZE indexFloatArray  :: ByteArray Int -> Int -> Float #-}
-{-# SPECIALIZE indexDoubleArray :: ByteArray Int -> Int -> Double #-}
-
-indexCharArray (ByteArray l u barr#) n
-  = case (index (l,u) n)               of { I# n# ->
-    case indexCharArray# barr# n#      of { r# ->
-    (C# r#)}}
-
-indexIntArray (ByteArray l u barr#) n
-  = case (index (l,u) n)               of { I# n# ->
-    case indexIntArray# barr# n#       of { r# ->
-    (I# r#)}}
-
-indexWordArray (ByteArray l u barr#) n
-  = case (index (l,u) n)               of { I# n# ->
-    case indexWordArray# barr# n#      of { r# ->
-    (W# r#)}}
-
-indexAddrArray (ByteArray l u barr#) n
-  = case (index (l,u) n)               of { I# n# ->
-    case indexAddrArray# barr# n#      of { r# ->
-    (A# r#)}}
-
-indexFloatArray (ByteArray l u barr#) n
-  = case (index (l,u) n)               of { I# n# ->
-    case indexFloatArray# barr# n#     of { r# ->
-    (F# r#)}}
-
-indexDoubleArray (ByteArray l u barr#) n
-  = case (index (l,u) n)               of { I# n# ->
-    case indexDoubleArray# barr# n#    of { r# ->
-    (D# r#)}}
-
-writeArray      :: Ix ix => MutableArray s ix elt -> ix -> elt -> ST s () 
-writeCharArray   :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s () 
-writeIntArray    :: Ix ix => MutableByteArray s ix -> ix -> Int  -> ST s () 
-writeWordArray   :: Ix ix => MutableByteArray s ix -> ix -> Word -> ST s () 
-writeAddrArray   :: Ix ix => MutableByteArray s ix -> ix -> Addr -> ST s () 
-writeFloatArray  :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s () 
-writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s () 
-
-{-# SPECIALIZE writeArray      :: MutableArray s Int elt -> Int -> elt -> ST s (),
-                                  MutableArray s IPr elt -> IPr -> elt -> ST s ()
+writeSTArray    :: Ix ix => STArray s ix elt -> ix -> elt -> ST s () 
+{-# SPECIALIZE writeSTArray :: STArray s Int elt -> Int -> elt -> ST s (),
+                              STArray s IPr elt -> IPr -> elt -> ST s ()
   #-}
-{-# SPECIALIZE writeCharArray   :: MutableByteArray s Int -> Int -> Char -> ST s () #-}
-{-# SPECIALIZE writeIntArray    :: MutableByteArray s Int -> Int -> Int  -> ST s () #-}
-{-# SPECIALIZE writeAddrArray   :: MutableByteArray s Int -> Int -> Addr -> ST s () #-}
---NO:{-# SPECIALIZE writeFloatArray  :: MutableByteArray s Int -> Int -> Float -> ST s () #-}
-{-# SPECIALIZE writeDoubleArray :: MutableByteArray s Int -> Int -> Double -> ST s () #-}
 
-writeArray (MutableArray l u arr#) n ele = ST $ \ s# ->
+writeSTArray (STArray l u arr#) n ele = ST $ \ s# ->
     case index (l,u) n                     of { I# n# ->
     case writeArray# arr# n# ele s#        of { s2# ->
     (# s2#, () #) }}
-
-writeCharArray (MutableByteArray l u barr#) n (C# ele) = ST $ \ s# ->
-    case index (l,u) n                     of { I# n# ->
-    case writeCharArray# barr# n# ele s#    of { s2#   ->
-    (# s2#, () #) }}
-
-writeIntArray (MutableByteArray l u barr#) n (I# ele) = ST $ \ s# ->
-    case index (l,u) n                     of { I# n# ->
-    case writeIntArray# barr# n# ele s#     of { s2#   ->
-    (# s2#, () #) }}
-
-writeWordArray (MutableByteArray l u barr#) n (W# ele) = ST $ \ s# ->
-    case index (l,u) n                     of { I# n# ->
-    case writeWordArray# barr# n# ele s#    of { s2#   ->
-    (# s2#, () #) }}
-
-writeAddrArray (MutableByteArray l u barr#) n (A# ele) = ST $ \ s# ->
-    case index (l,u) n                     of { I# n# ->
-    case writeAddrArray# barr# n# ele s#    of { s2#   ->
-    (# s2#, () #) }}
-
-writeFloatArray (MutableByteArray l u barr#) n (F# ele) = ST $ \ s# ->
-    case index (l,u) n                     of { I# n# ->
-    case writeFloatArray# barr# n# ele s#   of { s2#   ->
-    (# s2#, () #) }}
-
-writeDoubleArray (MutableByteArray l u barr#) n (D# ele) = ST $ \ s# ->
-    case index (l,u) n                     of { I# n# ->
-    case writeDoubleArray# barr# n# ele s#  of { s2#   ->
-    (# s2#, () #) }}
 \end{code}
 
 
@@ -428,32 +536,26 @@ writeDoubleArray (MutableByteArray l u barr#) n (D# ele) = ST $ \ s# ->
 %*********************************************************
 
 \begin{code}
-freezeArray      :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
-freezeCharArray   :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-freezeIntArray    :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-freezeWordArray   :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-freezeAddrArray   :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-
-{-# SPECIALISE freezeArray :: MutableArray s Int elt -> ST s (Array Int elt),
-                             MutableArray s IPr elt -> ST s (Array IPr elt)
+freezeSTArray    :: Ix ix => STArray s ix elt -> ST s (Array ix elt)
+{-# SPECIALISE freezeSTArray :: STArray s Int elt -> ST s (Array Int elt),
+                             STArray s IPr elt -> ST s (Array IPr elt)
   #-}
-{-# SPECIALISE freezeCharArray :: MutableByteArray s Int -> ST s (ByteArray Int) #-}
 
-freezeArray (MutableArray l u arr#) = ST $ \ s# ->
+freezeSTArray (STArray l u arr#) = ST $ \ s# ->
     case rangeSize (l,u)     of { I# n# ->
     case freeze arr# n# s# of { (# s2#, frozen# #) ->
     (# s2#, Array l u frozen# #) }}
-  where
-    freeze  :: MutableArray# s ele     -- the thing
-           -> Int#                     -- size of thing to be frozen
-           -> State# s                 -- the Universe and everything
-           -> (# State# s, Array# ele #)
-    freeze m_arr# n# s#
-      = case newArray# n# init s#            of { (# s2#, newarr1# #) ->
-       case copy 0# n# m_arr# newarr1# s2#   of { (# s3#, newarr2# #) ->
-       unsafeFreezeArray# newarr2# s3#
-       }}
-      where
+
+freeze  :: MutableArray# s ele -- the thing
+       -> Int#                 -- size of thing to be frozen
+       -> State# s                     -- the Universe and everything
+       -> (# State# s, Array# ele #)
+freeze m_arr# n# s#
+ = case newArray# n# init s#            of { (# s2#, newarr1# #) ->
+   case copy 0# n# m_arr# newarr1# s2#   of { (# s3#, newarr2# #) ->
+   unsafeFreezeArray# newarr2# s3#
+   }}
+ where
        init = error "freezeArray: element not copied"
 
        copy :: Int# -> Int#
@@ -471,163 +573,34 @@ freezeArray (MutableArray l u arr#) = ST $ \ s# ->
              copy (cur# +# 1#) end# from# to# s2#
              }}
 
-freezeCharArray (MutableByteArray l u arr#) = ST $ \ s# ->
-    case rangeSize (l,u)     of { I# n# ->
-    case freeze arr# n# s# of { (# s2#, frozen# #) ->
-    (# s2#, ByteArray l u frozen# #) }}
-  where
-    freeze  :: MutableByteArray# s     -- the thing
-           -> Int#                     -- size of thing to be frozen
-           -> State# s                 -- the Universe and everything
-           -> (# State# s, ByteArray# #)
-
-    freeze arr1# n# s1#
-      = case (newCharArray# n# s1#)                of { (# s2#, newarr1# #) ->
-       case copy 0# n# arr1# newarr1# s2#  of { (# s3#, newarr2# #) ->
-       unsafeFreezeByteArray# newarr2# s3#
-       }}
-      where
-       copy :: Int# -> Int#
-            -> MutableByteArray# s -> MutableByteArray# s
-            -> State# s
-            -> (# State# s, MutableByteArray# s #)
-
-       copy cur# end# from# to# st#
-         | cur# ==# end#
-           = (# st#, to# #)
-         | otherwise
-           = case (readCharArray#  from# cur#     st#) of { (# s2#, ele #) ->
-             case (writeCharArray# to#   cur# ele s2#) of { s3# ->
-             copy (cur# +# 1#) end# from# to# s3#
-             }}
-
-freezeIntArray (MutableByteArray l u arr#) = ST $ \ s# ->
-    case rangeSize (l,u)     of { I# n# ->
-    case freeze arr# n# s# of { (# s2#, frozen# #) ->
-    (# s2#, ByteArray l u frozen# #) }}
-  where
-    freeze  :: MutableByteArray# s     -- the thing
-           -> Int#                     -- size of thing to be frozen
-           -> State# s                 -- the Universe and everything
-           -> (# State# s, ByteArray# #)
-
-    freeze m_arr# n# s#
-      = case (newIntArray# n# s#)           of { (# s2#, newarr1# #) ->
-       case copy 0# n# m_arr# newarr1# s2#  of { (# s3#, newarr2# #) ->
-       unsafeFreezeByteArray# newarr2# s3#
-       }}
-      where
-       copy :: Int# -> Int#
-            -> MutableByteArray# s -> MutableByteArray# s
-            -> State# s
-            -> (# State# s, MutableByteArray# s #)
-
-       copy cur# end# from# to# s1#
-         | cur# ==# end#
-           = (# s1#, to# #)
-         | otherwise
-           = case (readIntArray#  from# cur#     s1#) of { (# s2#, ele #) ->
-             case (writeIntArray# to#   cur# ele s2#) of { s3# ->
-             copy (cur# +# 1#) end# from# to# s3#
-             }}
-
-freezeWordArray (MutableByteArray l u arr#) = ST $ \ s# ->
-    case rangeSize (l,u)     of { I# n# ->
-    case freeze arr# n# s# of { (# s2#, frozen# #) ->
-    (# s2#, ByteArray l u frozen# #) }}
-  where
-    freeze  :: MutableByteArray# s     -- the thing
-           -> Int#                     -- size of thing to be frozen
-           -> State# s                 -- the Universe and everything
-           -> (# State# s, ByteArray# #)
-
-    freeze m_arr# n# s1#
-      = case (newWordArray# n# s1#)                 of { (# s2#, newarr1# #) ->
-       case copy 0# n# m_arr# newarr1# s2#  of { (# s3#, newarr2# #) ->
-       unsafeFreezeByteArray# newarr2# s3#
-       }}
-      where
-       copy :: Int# -> Int#
-            -> MutableByteArray# s -> MutableByteArray# s
-            -> State# s
-            -> (# State# s, MutableByteArray# s #)
-
-       copy cur# end# from# to# st#
-         | cur# ==# end#  = (# st#, to# #)
-         | otherwise      =
-            case (readWordArray#  from# cur#     st#) of { (# s2#, ele #) ->
-            case (writeWordArray# to#   cur# ele s2#) of { s3# ->
-            copy (cur# +# 1#) end# from# to# s3#
-            }}
-
-freezeAddrArray (MutableByteArray l u arr#) = ST $ \ s# ->
-    case rangeSize (l,u)     of { I# n# ->
-    case freeze arr# n# s# of { (# s2#, frozen# #) ->
-    (# s2#, ByteArray l u frozen# #) }}
-  where
-    freeze  :: MutableByteArray# s     -- the thing
-           -> Int#                     -- size of thing to be frozen
-           -> State# s                 -- the Universe and everything
-           -> (# State# s, ByteArray# #)
-
-    freeze m_arr# n# s1#
-      = case (newAddrArray# n# s1#)                 of { (# s2#, newarr1# #) ->
-       case copy 0# n# m_arr# newarr1# s2#  of { (# s3#, newarr2# #) ->
-       unsafeFreezeByteArray# newarr2# s3#
-       }}
-      where
-       copy :: Int# -> Int#
-            -> MutableByteArray# s -> MutableByteArray# s
-            -> State# s
-            -> (# State# s, MutableByteArray# s #)
-
-       copy cur# end# from# to# st#
-         | cur# ==# end#
-           = (# st#, to# #)
-         | otherwise
-           = case (readAddrArray#  from# cur#     st#)  of { (# st1#, ele #) ->
-             case (writeAddrArray# to#   cur# ele st1#) of { st2# ->
-             copy (cur# +# 1#) end# from# to# st2#
-             }}
-
-unsafeFreezeArray     :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)  
-unsafeFreezeByteArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
-
-{-# SPECIALIZE unsafeFreezeByteArray :: MutableByteArray s Int -> ST s (ByteArray Int)
-  #-}
-
-unsafeFreezeArray (MutableArray l u arr#) = ST $ \ s# ->
+unsafeFreezeSTArray     :: Ix ix => STArray s ix elt -> ST s (Array ix elt)  
+unsafeFreezeSTArray (STArray l u arr#) = ST $ \ s# ->
     case unsafeFreezeArray# arr# s# of { (# s2#, frozen# #) ->
     (# s2#, Array l u frozen# #) }
 
-unsafeFreezeByteArray (MutableByteArray l u arr#) = ST $ \ s# ->
-    case unsafeFreezeByteArray# arr# s# of { (# s2#, frozen# #) ->
-    (# s2#, ByteArray l u frozen# #) }
-
-
 --This takes a immutable array, and copies it into a mutable array, in a
 --hurry.
 
-{-# SPECIALISE thawArray :: Array Int elt -> ST s (MutableArray s Int elt),
-                           Array IPr elt -> ST s (MutableArray s IPr elt)
+thawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
+{-# SPECIALISE thawSTArray :: Array Int elt -> ST s (STArray s Int elt),
+                             Array IPr elt -> ST s (STArray s IPr elt)
   #-}
 
-thawArray :: Ix ix => Array ix elt -> ST s (MutableArray s ix elt)
-thawArray (Array l u arr#) = ST $ \ s# ->
+thawSTArray (Array l u arr#) = ST $ \ s# ->
     case rangeSize (l,u) of { I# n# ->
     case thaw arr# n# s# of { (# s2#, thawed# #) ->
-    (# s2#, MutableArray l u thawed# #)}}
-  where
-    thaw  :: Array# ele                        -- the thing
-           -> Int#                     -- size of thing to be thawed
-           -> State# s                 -- the Universe and everything
-           -> (# State# s, MutableArray# s ele #)
+    (# s2#, STArray l u thawed# #)}}
 
-    thaw arr1# n# s#
-      = case newArray# n# init s#            of { (# s2#, newarr1# #) ->
-       copy 0# n# arr1# newarr1# s2# }
-      where
-       init = error "thawArray: element not copied"
+thaw  :: Array# ele            -- the thing
+      -> Int#                  -- size of thing to be thawed
+      -> State# s              -- the Universe and everything
+      -> (# State# s, MutableArray# s ele #)
+
+thaw arr1# n# s#
+  = case newArray# n# init s#        of { (# s2#, newarr1# #) ->
+    copy 0# n# arr1# newarr1# s2# }
+  where
+       init = error "thawSTArray: element not copied"
 
        copy :: Int# -> Int#
             -> Array# ele 
@@ -647,8 +620,8 @@ thawArray (Array l u arr#) = ST $ \ s# ->
 -- this is a quicker version of the above, just flipping the type
 -- (& representation) of an immutable array. And placing a
 -- proof obligation on the programmer.
-unsafeThawArray :: Ix ix => Array ix elt -> ST s (MutableArray s ix elt)
-unsafeThawArray (Array l u arr#) = ST $ \ s# ->
+unsafeThawSTArray :: Ix ix => Array ix elt -> ST s (STArray s ix elt)
+unsafeThawSTArray (Array l u arr#) = ST $ \ s# ->
    case unsafeThawArray# arr# s# of
-      (# s2#, marr# #) -> (# s2#, MutableArray l u marr# #)
+      (# s2#, marr# #) -> (# s2#, STArray l u marr# #)
 \end{code}