2 module Ix, -- export all of Ix
3 Array, array, listArray, (!), bounds, indices, elems, assocs,
4 accumArray, (//), accum, amap, ixmap ) where
10 -- This module specifies the semantics of arrays only: it is not
11 -- intended as an efficient implementation.
15 --Report:data (Ix a) => Array a b = MkArray (a,a) (a -> b) deriving ()
17 -- data Ix ix => Array ix elt = Array (ix, ix) (Array# elt)
19 --type IPr = (Int, Int)
21 {-# GENERATE_SPECS array a{~,Int,IPr} b{} #-}
22 array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
24 {-# GENERATE_SPECS listArray a{~,Int,IPr} b{} #-}
25 listArray :: (Ix a) => (a,a) -> [b] -> Array a b
27 {-# GENERATE_SPECS (!) a{~,Int,IPr} b{} #-}
28 (!) :: (Ix a) => Array a b -> a -> b
30 bounds :: (Ix a) => Array a b -> (a,a)
32 {-# GENERATE_SPECS indices a{~,Int,IPr} b{} #-}
33 indices :: (Ix a) => Array a b -> [a]
35 {-# GENERATE_SPECS elems a{~,Int,IPr} b{} #-}
36 elems :: (Ix a) => Array a b -> [b]
38 {-# GENERATE_SPECS assocs a{~,Int,IPr} b{} #-}
39 assocs :: (Ix a) => Array a b -> [(a,b)]
41 {-# GENERATE_SPECS (//) a{~,Int,IPr} b{} #-}
42 (//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b
44 {-# GENERATE_SPECS accum a{~,Int,IPr} b{} c{} #-}
45 accum :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
47 {-# GENERATE_SPECS accumArray a{~,Int,IPr} b{} c{} #-}
48 accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
50 {-# GENERATE_SPECS amap a{~,Int,IPr} b{} c{} #-}
51 amap :: (Ix a) => (b -> c) -> Array a b -> Array a c
53 ixmap :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c
55 -----------------------------------------------------------------------
56 {- "array", "!" and "bounds" are basic;
57 the rest can be defined in terms of them
60 bounds (Array b _) = b
62 (Array bounds arr#) ! i
63 = let n# = case (index bounds i) of { I# x -> x } -- index fails if out of range
65 case (indexArray# arr# n#) of
68 #ifdef USE_FOLDR_BUILD
71 array ixs@(ix_start, ix_end) ivs =
73 case (newArray ixs arrEleBottom) of { ST new_array_thing ->
74 case (new_array_thing s) of { (arr@(MutableArray _ arr#),s) ->
76 fill_one_in (S# s#) (i, v)
77 = case index ixs i of { I# n# ->
78 case writeArray# arr# n# v s# of { s2# ->
81 case (foldl fill_one_in s ivs) of { s@(S# _) ->
82 case (freezeArray arr) of { ST freeze_array_thing ->
83 freeze_array_thing s }}}})
85 arrEleBottom = error "(Array.!): undefined array element"
87 fill_it_in :: Ix ix => MutableArray s ix elt -> [(ix, elt)] -> ST s ()
89 = foldr fill_one_in (returnStrictlyST ()) lst
90 where -- **** STRICT **** (but that's OK...)
91 fill_one_in (i, v) rst
92 = writeArray arr i v `seqStrictlyST` rst
94 -----------------------------------------------------------------------
95 -- these also go better with magic: (//), accum, accumArray
99 -- copy the old array:
100 thawArray old_array `thenStrictlyST` \ arr# ->
101 -- now write the new elements into the new array:
102 fill_it_in arr# ivs `seqStrictlyST`
106 bottom = error "(Array.//): error in copying old array\n"
108 zap_with_f :: Ix ix => (elt -> elt2 -> elt) -> MutableArray s ix elt -> [(ix,elt2)] -> ST s ()
109 -- zap_with_f: reads an elem out first, then uses "f" on that and the new value
112 = foldr zap_one (returnStrictlyST ()) lst
114 zap_one (i, new_v) rst
115 = readArray arr i `thenStrictlyST` \ old_v ->
116 writeArray arr i (f old_v new_v) `seqStrictlyST`
121 -- copy the old array:
122 newArray (bounds arr) bottom >>= \ arr# ->
123 fill_it_in arr# (assocs arr) >>
125 -- now zap the elements in question with "f":
126 zap_with_f f arr# ivs >>
130 bottom = error "Array.accum: error in copying old array\n"
132 accumArray f zero ixs ivs
134 newArray ixs zero >>= \ arr# ->
135 zap_with_f f arr# ivs >>
139 -----------------------------------------------------------------------
141 listArray b vs = array b (zipWith (\ a b -> (a,b)) (range b) vs)
143 #ifdef USE_FOLDR_BUILD
144 {-# INLINE indices #-}
146 {-# INLINE assocs #-}
149 indices = range . bounds
151 elems a = [a!i | i <- indices a]
153 assocs a = [(i, a!i) | i <- indices a]
155 amap f a = array b [(i, f (a!i)) | i <- range b]
158 ixmap b f a = array b [(i, a ! f i) | i <- range b]