1 -- *** all of PreludeArray except the actual data decls
26 import IInt -- instances
30 import List ( (++), zipWith, foldr )
31 import Prel ( (&&), (.) )
32 import PS ( _PackedString, _unpackPS )
34 import TyArray ( Array(..), Assoc(..) )
38 -- Hey! This isn't wimp Haskell-report code! This is
39 -- the Business End of Arrays...
45 -----------------------------------------------------------
46 instance (Eq a, Eq b) => Eq (Assoc a b) where
47 (a1 := b1) == (a2 := b2) = a1 == a2 && b1 == b2
48 a /= b = if a == b then False else True
50 instance (Ord a, Ord b) => Ord (Assoc a b) where
51 a < b = case _tagCmp a b of { _LT -> True; _EQ -> False; _GT -> False }
52 a <= b = case _tagCmp a b of { _LT -> True; _EQ -> True; _GT -> False }
53 a >= b = case _tagCmp a b of { _LT -> False; _EQ -> True; _GT -> True }
54 a > b = case _tagCmp a b of { _LT -> False; _EQ -> False; _GT -> True }
55 max a b = case _tagCmp a b of { _LT -> b; _EQ -> a; _GT -> a }
56 min a b = case _tagCmp a b of { _LT -> a; _EQ -> a; _GT -> b }
57 _tagCmp (a1 := b1) (a2 := b2)
58 = case (_tagCmp a1 a2) of { _LT -> _LT; _GT -> _GT; _EQ -> _tagCmp b1 b2 }
60 instance (Ix a, Ix b) => Ix (Assoc a b) where
61 range (l1 := l2, u1 := u2)
62 = [ (i1 := i2) | i1 <- range (l1, u1), i2 <- range (l2, u2) ]
64 index (l1 := l2, u1 := u2) (i1 := i2)
65 = index (l1, u1) i1 * (index (l2, u2) u2 + 1){-rangeSize (l2, u2)-} + index (l2, u2) i2
67 inRange (l1 := l2, u1 := u2) (i1 := i2)
68 = inRange (l1, u1) i1 && inRange (l2, u2) i2
70 instance (Text a, Text b) => Text (Assoc a b) where
71 -- magic fixity wired in: infix 1 :=
74 (\ r -> [ (x := y, s2) | (x, s0) <- readsPrec 2 r,
76 (y, s2) <- readsPrec 2 s1 ])
79 (showsPrec 2 a . showString " := " . showsPrec 2 b)
81 readList = _readList (readsPrec 0)
82 showList = _showList (showsPrec 0)
86 -----------------------------------------------------------
90 {-# GENERATE_SPECS array a{~,Int,IPr} b{} #-}
91 array :: (Ix a) => (a,a) -> [Assoc a b] -> Array a b
93 {-# GENERATE_SPECS (!) a{~,Int,IPr} b{} #-}
94 (!) :: (Ix a) => Array a b -> a -> b
96 bounds :: Array a b -> (a,a)
98 {-# GENERATE_SPECS listArray a{~,Int,IPr} b{} #-}
99 listArray :: (Ix a) => (a,a) -> [b] -> Array a b
101 {-# GENERATE_SPECS indices a{~,Int,IPr} b{} #-}
102 indices :: (Ix a) => Array a b -> [a]
104 {-# GENERATE_SPECS elems a{~,Int,IPr} b{} #-}
105 elems :: (Ix a) => Array a b -> [b]
107 {-# GENERATE_SPECS assocs a{~,Int,IPr} b{} #-}
108 assocs :: (Ix a) => Array a b -> [Assoc a b]
110 {-# GENERATE_SPECS accumArray a{~,Int,IPr} b{} c{} #-}
111 accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [Assoc a c] -> Array a b
113 {-# GENERATE_SPECS (//) a{~,Int,IPr} b{} #-}
114 (//) :: (Ix a) => Array a b -> [Assoc a b] -> Array a b
116 {-# GENERATE_SPECS accum a{~,Int,IPr} b{} c{} #-}
117 accum :: (Ix a) => (b -> c -> b) -> Array a b -> [Assoc a c] -> Array a b
119 {-# GENERATE_SPECS amap a{~,Int,IPr} b{} c{} #-}
120 amap :: (Ix a) => (b -> c) -> Array a b -> Array a c
122 ixmap :: (Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c -> Array a c
125 {- "array", "!" and "bounds" are basic;
126 the rest can be defined in terms of them
129 bounds (_Array b _) = b
131 #ifdef USE_FOLDR_BUILD
134 array ixs@(ix_start, ix_end) ivs =
136 case _newArray ixs _arrEleBottom s of { (arr@(_MutableArray _ arr#),s) ->
138 fill_one_in (S# s#) (i := v)
139 = case index ixs i of { I# n# ->
140 case writeArray# arr# n# v s# of { s2# -> S# s2# }}
142 case foldl fill_one_in s ivs of { s@(S# _) ->
143 _freezeArray arr s }})
145 _arrEleBottom = error "(!){PreludeArray}: undefined array element"
148 array ixs@(ix_start, ix_end) ivs
150 newArray ixs arrEleBottom `thenStrictlyST` \ arr# ->
151 fill_it_in arr# ivs `seqStrictlyST`
155 arrEleBottom = error "(!){PreludeArray}: undefined array element"
158 (_Array bounds arr#) ! i
159 = let n# = case (index bounds i) of { I# x -> x } -- index fails if out of range
161 case (indexArray# arr# n#) of
165 = foldr fill_one_in (returnStrictlyST ()) lst s
166 where -- **** STRICT **** (but that's OK...)
167 fill_one_in (i := v) rst s
168 = (writeArray arr i v `seqStrictlyST` rst) s
170 {- the rest ------------------------------------------------- -}
172 listArray b vs = array b (zipWith (:=) (range b) vs)
174 #ifdef USE_FOLDR_BUILD
175 {-# INLINE indices #-}
177 {-# INLINE assocs #-}
180 indices a = range (bounds a)
182 elems a = [a!i | i <- indices a]
184 assocs a = [i := a!i | i <- indices a]
186 #ifdef USE_REPORT_PRELUDE
187 a // us = array (bounds a)
188 ([i := a!i | i <- indices a \\ [i | i:=_ <- us]]
191 accum f = foldl (\a (i := v) -> a // [i := f (a!i) v])
193 accumArray f z b = accum f (array b [i := z | i <- range b])
195 #else /* ! USE_REPORT_PRELUDE */
197 -- TODO: add (//), accum, accumArray, listArray
201 -- copy the old array:
202 thawArray old_array `thenStrictlyST` \ arr# ->
203 -- now write the new elements into the new array:
204 fill_it_in arr# ivs `seqStrictlyST`
208 bottom = error "(//){PreludeArray}: error in copying old array\n"
210 -- zap_with_f: reads an elem out first, then uses "f" on that and the new value
212 zap_with_f f arr lst s
213 = foldr zap_one (returnStrictlyST ()) lst s
215 zap_one (i := new_v) rst s
216 = (readArray arr i `thenStrictlyST` \ old_v ->
217 writeArray arr i (f old_v new_v) `seqStrictlyST`
222 -- copy the old array:
223 newArray (bounds arr) bottom `thenST` \ arr# ->
224 fill_it_in arr# (assocs arr) `seqST`
226 -- now zap the elements in question with "f":
227 zap_with_f f arr# ivs `seqST`
231 bottom = error "accum{PreludeArray}: error in copying old array\n"
233 accumArray f zero ixs ivs
235 newArray ixs zero `thenST` \ arr# ->
236 zap_with_f f arr# ivs `seqST`
239 #endif /* ! USE_REPORT_PRELUDE */
241 amap f a = array b [i := f (a!i) | i <- range b]
244 ixmap b f a = array b [i := a ! f i | i <- range b]
246 instance (Ix a, Eq b) => Eq (Array a b) where
247 a == a' = assocs a == assocs a'
248 a /= a' = assocs a /= assocs a'
250 instance (Ix a, Ord b) => Ord (Array a b) where
251 a < b = case _tagCmp a b of { _LT -> True; _EQ -> False; _GT -> False }
252 a <= b = case _tagCmp a b of { _LT -> True; _EQ -> True; _GT -> False }
253 a >= b = case _tagCmp a b of { _LT -> False; _EQ -> True; _GT -> True }
254 a > b = case _tagCmp a b of { _LT -> False; _EQ -> False; _GT -> True }
256 max a b = case _tagCmp a b of { _LT -> b; _EQ -> a; _GT -> a }
257 min a b = case _tagCmp a b of { _LT -> a; _EQ -> a; _GT -> b }
259 _tagCmp a b = _tagCmp (assocs a) (assocs b)
261 instance (Ix a, Text a, Text b) => Text (Array a b) where
262 showsPrec p a = showParen (p > 9) (
263 showString "array " .
264 showsPrec 0 (bounds a) . showChar ' ' .
265 showList (assocs a) )
267 readsPrec p = readParen (p > 9)
268 (\r -> [(array b as, u) | ("array",s) <- lex r,
269 (b,t) <- readsPrec 0 s,
270 (as,u) <- readList t ]
272 [(listArray b xs, u) | ("listArray",s) <- lex r,
273 (b,t) <- readsPrec 0 s,
274 (xs,u) <- readList t ])
276 readList = _readList (readsPrec 0)
277 showList = _showList (showsPrec 0)
280 {-# SPECIALIZE instance Text (Array Int Double) #-}
281 {-# SPECIALIZE instance Text (Array (Int,Int) Double) #-}
283 {- **** OMITTED **** (ToDo)
284 instance (Ix a, Binary a, Binary b) => Binary (Array a b) where
285 showBin a = showBin (bounds a) . showBin (elems a)
287 readBin bin = (listArray b vs, bin'')
288 where (b,bin') = readBin bin
289 (vs,bin'') = readBin bin'
293 #if defined(__UNBOXED_INSTANCES__)
295 -- {-# GENERATE_SPECS array a{~,Int#,Int,IPr} b{Int#,Double#} #-}
296 -- {-# GENERATE_SPECS (!) a{~,Int#,Int,IPr} b{Int#,Double#} #-}
297 -- {-# GENERATE_SPECS bounds a{~,Int#} b{Int#,Double#} #-}
298 -- {-# GENERATE_SPECS listArray a{~,Int#,Int,IPr} b{Int#,Double#} #-}
299 -- {-# GENERATE_SPECS indices a{~,Int#,Int,IPr} b{Int#,Double#} #-}
300 -- {-# GENERATE_SPECS elems a{~,Int#,Int,IPr} b{Int#,Double#} #-}
301 -- {-# GENERATE_SPECS assocs a{~,Int#,Int,IPr} b{Int#,Double#} #-}
302 -- {-# GENERATE_SPECS accumArray a{~,Int#,Int,IPr} b{Int#,Double#} c{Int#,Double#} #-}
303 -- {-# GENERATE_SPECS (//) a{~,Int#,Int,IPr} b{Int#,Double#} #-}
304 -- {-# GENERATE_SPECS accum a{~,Int#,Int,IPr} b{Int#,Double#} c{Int#,Double#} #-}
305 -- {-# GENERATE_SPECS amap a{~,Int#,Int,IPr} b{Int#,Double#} c{Int#,Double#} #-}
306 -- {-# GENERATE_SPECS ixmap a{~,Int#,Int} b{~,Int#,Int} c{Int#,Double#} #-}
308 -- {-# GENERATE_SPECS instance a{Int#} b{Int#,Double#} :: Eq (Array a b) #-}
309 -- {-# GENERATE_SPECS instance a{Int#} b{Int#,Double#} :: Ord (Array a b) #-}
310 -- {-# GENERATE_SPECS instance a{Int#} b{Int#,Double#} :: Text (Array a b) #-}
312 -- {-# GENERATE_SPECS instance a{Int#} b{Int#,Double#} :: Eq (Assoc a b) #-}
313 -- {-# GENERATE_SPECS instance a{Int#} b{Int#,Double#} :: Ord (Assoc a b) #-}
314 -- {-# GENERATE_SPECS instance a{Int#} b{Int#,Double#} :: Ix (Assoc a b) #-}
315 -- {-# GENERATE_SPECS instance a{Int#} b{Int#,Double#} :: Text (Assoc a b) #-}