A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/src/GHC-Arr.html below:

GHC/Arr.lhs

\begin{code}




















module GHC.Arr (
        Ix(..), Array(..), STArray(..),

        indexError, hopelessIndexError,
        arrEleBottom, array, listArray,
        (!), safeRangeSize, negRange, safeIndex, badSafeIndex,
        bounds, numElements, numElementsSTArray, indices, elems,
        assocs, accumArray, adjust, (//), accum,
        amap, ixmap,
        eqArray, cmpArray, cmpIntArray,
        newSTArray, boundsSTArray,
        readSTArray, writeSTArray,
        freezeSTArray, thawSTArray,

        
        fill, done,
        unsafeArray, unsafeArray',
        lessSafeIndex, unsafeAt, unsafeReplace,
        unsafeAccumArray, unsafeAccumArray', unsafeAccum,
        unsafeReadSTArray, unsafeWriteSTArray,
        unsafeFreezeSTArray, unsafeThawSTArray,
    ) where

import GHC.Enum
import GHC.Num
import GHC.ST
import GHC.Base
import GHC.List
import GHC.Show

infixl 9  !, //

default ()
\end{code} %********************************************************* %* * \subsection{The @Ix@ class} %* * %********************************************************* \begin{code}




















class (Ord a) => Ix a where
    
    range               :: (a,a) -> [a]
    
    index               :: (a,a) -> a -> Int
    
    unsafeIndex         :: (a,a) -> a -> Int
    
    
    inRange             :: (a,a) -> a -> Bool
    
    rangeSize           :: (a,a) -> Int
    
    
    unsafeRangeSize     :: (a,a) -> Int

        

	
	
	
      
    index b i | inRange b i = unsafeIndex b i   
              | otherwise   = hopelessIndexError

    unsafeIndex b i = index b i

    rangeSize b@(_l,h) | inRange b h = unsafeIndex b h + 1
                       | otherwise   = 0        
                                                
        
        

    unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
\end{code} 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 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 ) "" ) hopelessIndexError :: Int hopelessIndexError = error "Error in array index" instance Ix Char where range ( m , n ) = [ m .. n ] 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 range ( m , n ) = [ m .. n ] unsafeIndex ( m , _n ) i = i m index b i | inRange b i = unsafeIndex b i | otherwise = indexError b i "Int" inRange ( I # m , I # n ) ( I # i ) = m <=# i && i <=# n instance Ix Integer where range ( m , n ) = [ m .. n ] 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 range ( m , n ) = [ m .. n ] 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 range ( m , n ) = [ m .. n ] 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 range ( () , () ) = [ () ] unsafeIndex ( () , () ) () = 0 inRange ( () , () ) () = True index b i = unsafeIndex b i instance ( Ix a , Ix b ) => Ix ( a , b ) where range ( ( l1 , l2 ) , ( u1 , u2 ) ) = [ ( i1 , i2 ) | i1 <- range ( l1 , u1 ) , i2 <- range ( l2 , u2 ) ] unsafeIndex ( ( l1 , l2 ) , ( u1 , u2 ) ) ( i1 , i2 ) = unsafeIndex ( l1 , u1 ) i1 * unsafeRangeSize ( l2 , u2 ) + unsafeIndex ( l2 , u2 ) i2 inRange ( ( l1 , l2 ) , ( u1 , u2 ) ) ( i1 , i2 ) = inRange ( l1 , u1 ) i1 && inRange ( l2 , u2 ) i2 instance ( Ix a1 , Ix a2 , Ix a3 ) => Ix ( a1 , a2 , a3 ) where 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 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 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 \end{code} %********************************************************* %* * \subsection{The @Array@ types} %* * %********************************************************* \begin{code}


data Array i e
         = Array !i         
                 !i         
                 !Int       
                            
                            
                 (Array# e) 










data STArray s i e
         = STArray !i                  
                   !i                  
                   !Int                
                                       
                                       
                   (MutableArray# s e) 
        
        


instance Eq (STArray s i e) where
    STArray _ _ _ arr1# == STArray _ _ _ arr2# =
        sameMutableArray# arr1# arr2#
\end{code} %********************************************************* %* * \subsection{Operations on immutable arrays} %* * %********************************************************* \begin{code}

arrEleBottom :: a
arrEleBottom = error "(Array.!): undefined array element"



























array :: Ix i
        => (i,i)        
                        
                        
                        
                        
                        
        -> [(i, e)]     
                        
                        
                        
                        
        -> Array i e
array (l,u) ies
    = let n = safeRangeSize (l,u)
      in unsafeArray' (l,u) n
                      [(safeIndex (l,u) n i, e) | (i, e) <- ies]


unsafeArray :: Ix i => (i,i) -> [(Int, e)] -> Array i e
unsafeArray b ies = unsafeArray' b (rangeSize b) ies


unsafeArray' :: Ix i => (i,i) -> Int -> [(Int, e)] -> Array i e
unsafeArray' (l,u) n@(I# n#) ies = runST (ST $ \s1# ->
    case newArray# n# arrEleBottom s1# of
        (# s2#, marr# #) ->
            foldr (fill marr#) (done l u n marr#) ies s2#)


fill :: MutableArray# s e -> (Int, e) -> STRep s a -> STRep s a


fill marr# (I# i#, e) next 
 = \s1# -> case writeArray# marr# i# e s1# of 
             s2# -> next s2# 


done :: Ix i => i -> i -> Int -> MutableArray# s e -> STRep s (Array i e)

done l u n marr# 
  = \s1# -> case unsafeFreezeArray# marr# s1# of
              (# s2#, arr# #) -> (# s2#, Array l u n arr# #)










listArray :: Ix i => (i,i) -> [e] -> Array i e
listArray (l,u) es = runST (ST $ \s1# ->
    case safeRangeSize (l,u)            of { n@(I# n#) ->
    case newArray# n# arrEleBottom s1#  of { (# s2#, marr# #) ->
    let fillFromList i# xs s3# | i# ==# n# = s3#
                               | otherwise = case xs of
            []   -> s3#
            y:ys -> case writeArray# marr# i# y s3# of { s4# ->
                    fillFromList (i# +# 1#) ys s4# } in
    case fillFromList 0# es s2#         of { s3# ->
    done l u n marr# s3# }}})



(!) :: Ix i => Array i e -> i -> e
arr@(Array l u n _) ! i = unsafeAt arr $ safeIndex (l,u) n i


safeRangeSize :: Ix i => (i, i) -> Int
safeRangeSize (l,u) = let r = rangeSize (l, u)
                      in if r < 0 then negRange
                                  else r


negRange :: Int	  
negRange = error "Negative range size"




safeIndex :: Ix i => (i, i) -> Int -> i -> Int
safeIndex (l,u) n i = let i' = index (l,u) i
                      in if (0 <= i') && (i' < n)
                         then i'
                         else badSafeIndex i' n




lessSafeIndex :: Ix i => (i, i) -> Int -> i -> Int


lessSafeIndex (l,u) _ i = index (l,u) i  


badSafeIndex :: Int -> Int -> Int
badSafeIndex i' n = error ("Error in array index; " ++ show i' ++
                        " not in range [0.." ++ show n ++ ")")


unsafeAt :: Ix i => Array i e -> Int -> e
unsafeAt (Array _ _ _ arr#) (I# i#) =
    case indexArray# arr# i# of (# e #) -> e



bounds :: Ix i => Array i e -> (i,i)
bounds (Array l u _ _) = (l,u)



numElements :: Ix i => Array i e -> Int
numElements (Array _ _ n _) = n



indices :: Ix i => Array i e -> [i]
indices (Array l u _ _) = range (l,u)



elems :: Ix i => Array i e -> [e]
elems arr@(Array _ _ n _) =
    [unsafeAt arr i | i <- [0 .. n  1]]



assocs :: Ix i => Array i e -> [(i, e)]
assocs arr@(Array l u _ _) =
    [(i, arr ! i) | i <- range (l,u)]
















accumArray :: Ix i
        => (e -> a -> e)        
        -> e                    
        -> (i,i)                
        -> [(i, a)]             
        -> Array i e
accumArray f initial (l,u) ies =
    let n = safeRangeSize (l,u)
    in unsafeAccumArray' f initial (l,u) n
                         [(safeIndex (l,u) n i, e) | (i, e) <- ies]


unsafeAccumArray :: Ix i => (e -> a -> e) -> e -> (i,i) -> [(Int, a)] -> Array i e
unsafeAccumArray f initial b ies = unsafeAccumArray' f initial b (rangeSize b) ies


unsafeAccumArray' :: Ix i => (e -> a -> e) -> e -> (i,i) -> Int -> [(Int, a)] -> Array i e
unsafeAccumArray' f initial (l,u) n@(I# n#) ies = runST (ST $ \s1# ->
    case newArray# n# initial s1#          of { (# s2#, marr# #) ->
    foldr (adjust f marr#) (done l u n marr#) ies s2# })


adjust :: (e -> a -> e) -> MutableArray# s e -> (Int, a) -> STRep s b -> STRep s b

adjust f marr# (I# i#, new) next
  = \s1# -> case readArray# marr# i# s1# of
        	(# s2#, old #) ->
        	    case writeArray# marr# i# (f old new) s2# of
        	        s3# -> next s3#













(//) :: Ix i => Array i e -> [(i, e)] -> Array i e
arr@(Array l u n _) // ies =
    unsafeReplace arr [(safeIndex (l,u) n i, e) | (i, e) <- ies]


unsafeReplace :: Ix i => Array i e -> [(Int, e)] -> Array i e
unsafeReplace arr ies = runST (do
    STArray l u n marr# <- thawSTArray arr
    ST (foldr (fill marr#) (done l u n marr#) ies))








accum :: Ix i => (e -> a -> e) -> Array i e -> [(i, a)] -> Array i e
accum f arr@(Array l u n _) ies =
    unsafeAccum f arr [(safeIndex (l,u) n i, e) | (i, e) <- ies]


unsafeAccum :: Ix i => (e -> a -> e) -> Array i e -> [(Int, a)] -> Array i e
unsafeAccum f arr ies = runST (do
    STArray l u n marr# <- thawSTArray arr
    ST (foldr (adjust f marr#) (done l u n marr#) ies))


amap :: Ix i => (a -> b) -> Array i a -> Array i b
amap f arr@(Array l u n _) =
    unsafeArray' (l,u) n [(i, f (unsafeAt arr i)) | i <- [0 .. n  1]]








ixmap :: (Ix i, Ix j) => (i,i) -> (i -> j) -> Array j e -> Array i e
ixmap (l,u) f arr =
    array (l,u) [(i, arr ! f i) | i <- range (l,u)]


eqArray :: (Ix i, Eq e) => Array i e -> Array i e -> Bool
eqArray arr1@(Array l1 u1 n1 _) arr2@(Array l2 u2 n2 _) =
    if n1 == 0 then n2 == 0 else
    l1 == l2 && u1 == u2 &&
    and [unsafeAt arr1 i == unsafeAt arr2 i | i <- [0 .. n1  1]]


cmpArray :: (Ix i, Ord e) => Array i e -> Array i e -> Ordering
cmpArray arr1 arr2 = compare (assocs arr1) (assocs arr2)


cmpIntArray :: Ord e => Array Int e -> Array Int e -> Ordering
cmpIntArray arr1@(Array l1 u1 n1 _) arr2@(Array l2 u2 n2 _) =
    if n1 == 0 then
        if n2 == 0 then EQ else LT
    else if n2 == 0 then GT
    else case compare l1 l2 of
             EQ    -> foldr cmp (compare u1 u2) [0 .. (n1 `min` n2)  1]
             other -> other
  where
    cmp i rest = case compare (unsafeAt arr1 i) (unsafeAt arr2 i) of
        EQ    -> rest
        other -> other


\end{code} %********************************************************* %* * \subsection{Array instances} %* * %********************************************************* \begin{code}
instance Ix i => Functor (Array i) where
    fmap = amap

instance (Ix i, Eq e) => Eq (Array i e) where
    (==) = eqArray

instance (Ix i, Ord e) => Ord (Array i e) where
    compare = cmpArray

instance (Ix a, Show a, Show b) => Show (Array a b) where
    showsPrec p a =
        showParen (p > appPrec) $
        showString "array " .
        showsPrec appPrec1 (bounds a) .
        showChar ' ' .
        showsPrec appPrec1 (assocs a)
        


\end{code} %********************************************************* %* * \subsection{Operations on mutable arrays} %* * %********************************************************* Idle ADR question: What's the tradeoff here between flattening these 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 required by many array-related functions. Which wins? Is the difference significant (probably not). Idle AJG answer: When I looked at the outputted code (though it was 2 years ago) it seems like you often needed the tuple, and we build it frequently. Now we've got the overloading specialiser things might be different, though. \begin{code}

newSTArray :: Ix i => (i,i) -> e -> ST s (STArray s i e)
newSTArray (l,u) initial = ST $ \s1# ->
    case safeRangeSize (l,u)            of { n@(I# n#) ->
    case newArray# n# initial s1#       of { (# s2#, marr# #) ->
    (# s2#, STArray l u n marr# #) }}


boundsSTArray :: STArray s i e -> (i,i)  
boundsSTArray (STArray l u _ _) = (l,u)


numElementsSTArray :: STArray s i e -> Int
numElementsSTArray (STArray _ _ n _) = n


readSTArray :: Ix i => STArray s i e -> i -> ST s e
readSTArray marr@(STArray l u n _) i =
    unsafeReadSTArray marr (safeIndex (l,u) n i)


unsafeReadSTArray :: Ix i => STArray s i e -> Int -> ST s e
unsafeReadSTArray (STArray _ _ _ marr#) (I# i#)
    = ST $ \s1# -> readArray# marr# i# s1#


writeSTArray :: Ix i => STArray s i e -> i -> e -> ST s () 
writeSTArray marr@(STArray l u n _) i e =
    unsafeWriteSTArray marr (safeIndex (l,u) n i) e


unsafeWriteSTArray :: Ix i => STArray s i e -> Int -> e -> ST s () 
unsafeWriteSTArray (STArray _ _ _ marr#) (I# i#) e = ST $ \s1# ->
    case writeArray# marr# i# e s1# of
        s2# -> (# s2#, () #)
\end{code} %********************************************************* %* * \subsection{Moving between mutable and immutable} %* * %********************************************************* \begin{code}
freezeSTArray :: Ix i => STArray s i e -> ST s (Array i e)
freezeSTArray (STArray l u n@(I# n#) marr#) = ST $ \s1# ->
    case newArray# n# arrEleBottom s1#  of { (# s2#, marr'# #) ->
    let copy i# s3# | i# ==# n# = s3#
                    | otherwise =
            case readArray# marr# i# s3# of { (# s4#, e #) ->
            case writeArray# marr'# i# e s4# of { s5# ->
            copy (i# +# 1#) s5# }} in
    case copy 0# s2#                    of { s3# ->
    case unsafeFreezeArray# marr'# s3#  of { (# s4#, arr# #) ->
    (# s4#, Array l u n arr# #) }}}


unsafeFreezeSTArray :: Ix i => STArray s i e -> ST s (Array i e)
unsafeFreezeSTArray (STArray l u n marr#) = ST $ \s1# ->
    case unsafeFreezeArray# marr# s1#   of { (# s2#, arr# #) ->
    (# s2#, Array l u n arr# #) }

thawSTArray :: Ix i => Array i e -> ST s (STArray s i e)
thawSTArray (Array l u n@(I# n#) arr#) = ST $ \s1# ->
    case newArray# n# arrEleBottom s1#  of { (# s2#, marr# #) ->
    let copy i# s3# | i# ==# n# = s3#
                    | otherwise =
            case indexArray# arr# i#    of { (# e #) ->
            case writeArray# marr# i# e s3# of { s4# ->
            copy (i# +# 1#) s4# }} in
    case copy 0# s2#                    of { s3# ->
    (# s3#, STArray l u n marr# #) }}


unsafeThawSTArray :: Ix i => Array i e -> ST s (STArray s i e)
unsafeThawSTArray (Array l u n arr#) = ST $ \s1# ->
    case unsafeThawArray# arr# s1#      of { (# s2#, marr# #) ->
    (# s2#, STArray l u n marr# #) }
\end{code}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4