2 % (c) The AQUA Project, Glasgow University, 1994-1996
4 \section[ArrBase]{Module @ArrBase@}
6 Array implementation, @ArrBase@ exports the basic array
10 {-# OPTIONS -fno-implicit-prelude #-}
14 import {-# SOURCE #-} IOBase ( error )
16 import PrelList (foldl)
26 {-# GENERATE_SPECS array a{~,Int,IPr} b{} #-}
27 array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
29 {-# GENERATE_SPECS (!) a{~,Int,IPr} b{} #-}
30 (!) :: (Ix a) => Array a b -> a -> b
32 bounds :: (Ix a) => Array a b -> (a,a)
34 {-# GENERATE_SPECS (//) a{~,Int,IPr} b{} #-}
35 (//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b
37 {-# GENERATE_SPECS accum a{~,Int,IPr} b{} c{} #-}
38 accum :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
40 {-# GENERATE_SPECS accumArray a{~,Int,IPr} b{} c{} #-}
41 accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
45 %*********************************************************
47 \subsection{The @Array@ types}
49 %*********************************************************
54 data Ix ix => Array ix elt = Array (ix,ix) (Array# elt)
55 data Ix ix => ByteArray ix = ByteArray (ix,ix) ByteArray#
56 data Ix ix => MutableArray s ix elt = MutableArray (ix,ix) (MutableArray# s elt)
57 data Ix ix => MutableByteArray s ix = MutableByteArray (ix,ix) (MutableByteArray# s)
59 instance CCallable (MutableByteArray s ix)
60 instance CCallable (MutableByteArray# s)
62 instance CCallable (ByteArray ix)
63 instance CCallable ByteArray#
65 -- A one-element mutable array:
66 type MutableVar s a = MutableArray s Int a
70 %*********************************************************
72 \subsection{Operations on immutable arrays}
74 %*********************************************************
76 "array", "!" and "bounds" are basic; the rest can be defined in terms of them
79 bounds (Array b _) = b
81 (Array bounds arr#) ! i
82 = let n# = case (index bounds i) of { I# x -> x } -- index fails if out of range
84 case (indexArray# arr# n#) of
87 #ifdef USE_FOLDR_BUILD
90 array ixs@(ix_start, ix_end) ivs =
92 case (newArray ixs arrEleBottom) of { ST new_array_thing ->
93 case (new_array_thing s) of { (arr@(MutableArray _ arr#),s) ->
95 fill_one_in (S# s#) (i, v)
96 = case index ixs i of { I# n# ->
97 case writeArray# arr# n# v s# of { s2# ->
100 case (foldl fill_one_in s ivs) of { s@(S# _) ->
101 case (freezeArray arr) of { ST freeze_array_thing ->
102 freeze_array_thing s }}}})
104 arrEleBottom = error "(Array.!): undefined array element"
106 fill_it_in :: Ix ix => MutableArray s ix elt -> [(ix, elt)] -> ST s ()
108 = foldr fill_one_in (returnST ()) lst
109 where -- **** STRICT **** (but that's OK...)
110 fill_one_in (i, v) rst
111 = writeArray arr i v `seqST` rst
113 -----------------------------------------------------------------------
114 -- these also go better with magic: (//), accum, accumArray
118 -- copy the old array:
119 thawArray old_array `thenST` \ arr ->
120 -- now write the new elements into the new array:
121 fill_it_in arr ivs `seqST`
125 bottom = error "(Array.//): error in copying old array\n"
127 zap_with_f :: Ix ix => (elt -> elt2 -> elt) -> MutableArray s ix elt -> [(ix,elt2)] -> ST s ()
128 -- zap_with_f: reads an elem out first, then uses "f" on that and the new value
131 = foldr zap_one (returnST ()) lst
133 zap_one (i, new_v) rst
134 = readArray arr i `thenST` \ old_v ->
135 writeArray arr i (f old_v new_v) `seqST`
138 accum f old_array ivs
140 -- copy the old array:
141 thawArray old_array `thenST` \ arr ->
143 -- now zap the elements in question with "f":
144 zap_with_f f arr ivs >>
148 bottom = error "Array.accum: error in copying old array\n"
150 accumArray f zero ixs ivs
152 newArray ixs zero >>= \ arr# ->
153 zap_with_f f arr# ivs >>
159 %*********************************************************
161 \subsection{Operations on mutable arrays}
163 %*********************************************************
165 Idle ADR question: What's the tradeoff here between flattening these
166 datatypes into @MutableArray ix ix (MutableArray# s elt)@ and using
167 it as is? As I see it, the former uses slightly less heap and
168 provides faster access to the individual parts of the bounds while the
169 code used has the benefit of providing a ready-made @(lo, hi)@ pair as
170 required by many array-related functions. Which wins? Is the
171 difference significant (probably not).
173 Idle AJG answer: When I looked at the outputted code (though it was 2
174 years ago) it seems like you often needed the tuple, and we build
175 it frequently. Now we've got the overloading specialiser things
176 might be different, though.
179 newArray :: Ix ix => (ix,ix) -> elt -> ST s (MutableArray s ix elt)
180 newCharArray, newIntArray, newAddrArray, newFloatArray, newDoubleArray
181 :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
183 {-# SPECIALIZE newArray :: IPr -> elt -> ST s (MutableArray s Int elt),
184 (IPr,IPr) -> elt -> ST s (MutableArray s IPr elt)
186 {-# SPECIALIZE newCharArray :: IPr -> ST s (MutableByteArray s Int) #-}
187 {-# SPECIALIZE newIntArray :: IPr -> ST s (MutableByteArray s Int) #-}
188 {-# SPECIALIZE newAddrArray :: IPr -> ST s (MutableByteArray s Int) #-}
189 {-# SPECIALIZE newFloatArray :: IPr -> ST s (MutableByteArray s Int) #-}
190 {-# SPECIALIZE newDoubleArray :: IPr -> ST s (MutableByteArray s Int) #-}
192 newArray ixs init = ST $ \ (S# s#) ->
193 case rangeSize ixs of { I# n# ->
194 case (newArray# n# init s#) of { StateAndMutableArray# s2# arr# ->
195 (MutableArray ixs arr#, S# s2#)}}
197 newCharArray ixs = ST $ \ (S# s#) ->
198 case rangeSize ixs of { I# n# ->
199 case (newCharArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
200 (MutableByteArray ixs barr#, S# s2#)}}
202 newIntArray ixs = ST $ \ (S# s#) ->
203 case rangeSize ixs of { I# n# ->
204 case (newIntArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
205 (MutableByteArray ixs barr#, S# s2#)}}
207 newAddrArray ixs = ST $ \ (S# s#) ->
208 case rangeSize ixs of { I# n# ->
209 case (newAddrArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
210 (MutableByteArray ixs barr#, S# s2#)}}
212 newFloatArray ixs = ST $ \ (S# s#) ->
213 case rangeSize ixs of { I# n# ->
214 case (newFloatArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
215 (MutableByteArray ixs barr#, S# s2#)}}
217 newDoubleArray ixs = ST $ \ (S# s#) ->
218 case rangeSize ixs of { I# n# ->
219 case (newDoubleArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
220 (MutableByteArray ixs barr#, S# s2#)}}
222 boundsOfArray :: Ix ix => MutableArray s ix elt -> (ix, ix)
223 boundsOfByteArray :: Ix ix => MutableByteArray s ix -> (ix, ix)
225 {-# SPECIALIZE boundsOfArray :: MutableArray s Int elt -> IPr #-}
226 {-# SPECIALIZE boundsOfByteArray :: MutableByteArray s Int -> IPr #-}
228 boundsOfArray (MutableArray ixs _) = ixs
229 boundsOfByteArray (MutableByteArray ixs _) = ixs
231 readArray :: Ix ix => MutableArray s ix elt -> ix -> ST s elt
233 readCharArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Char
234 readIntArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
235 readAddrArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Addr
236 readFloatArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
237 readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
239 {-# SPECIALIZE readArray :: MutableArray s Int elt -> Int -> ST s elt,
240 MutableArray s IPr elt -> IPr -> ST s elt
242 {-# SPECIALIZE readCharArray :: MutableByteArray s Int -> Int -> ST s Char #-}
243 {-# SPECIALIZE readIntArray :: MutableByteArray s Int -> Int -> ST s Int #-}
244 {-# SPECIALIZE readAddrArray :: MutableByteArray s Int -> Int -> ST s Addr #-}
245 --NO:{-# SPECIALIZE readFloatArray :: MutableByteArray s Int -> Int -> ST s Float #-}
246 {-# SPECIALIZE readDoubleArray :: MutableByteArray s Int -> Int -> ST s Double #-}
248 readArray (MutableArray ixs arr#) n = ST $ \ (S# s#) ->
249 case (index ixs n) of { I# n# ->
250 case readArray# arr# n# s# of { StateAndPtr# s2# r ->
253 readCharArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
254 case (index ixs n) of { I# n# ->
255 case readCharArray# barr# n# s# of { StateAndChar# s2# r# ->
258 readIntArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
259 case (index ixs n) of { I# n# ->
260 case readIntArray# barr# n# s# of { StateAndInt# s2# r# ->
263 readAddrArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
264 case (index ixs n) of { I# n# ->
265 case readAddrArray# barr# n# s# of { StateAndAddr# s2# r# ->
268 readFloatArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
269 case (index ixs n) of { I# n# ->
270 case readFloatArray# barr# n# s# of { StateAndFloat# s2# r# ->
273 readDoubleArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
274 case (index ixs n) of { I# n# ->
275 case readDoubleArray# barr# n# s# of { StateAndDouble# s2# r# ->
278 --Indexing of ordinary @Arrays@ is standard Haskell and isn't defined here.
279 indexCharArray :: Ix ix => ByteArray ix -> ix -> Char
280 indexIntArray :: Ix ix => ByteArray ix -> ix -> Int
281 indexAddrArray :: Ix ix => ByteArray ix -> ix -> Addr
282 indexFloatArray :: Ix ix => ByteArray ix -> ix -> Float
283 indexDoubleArray :: Ix ix => ByteArray ix -> ix -> Double
285 {-# SPECIALIZE indexCharArray :: ByteArray Int -> Int -> Char #-}
286 {-# SPECIALIZE indexIntArray :: ByteArray Int -> Int -> Int #-}
287 {-# SPECIALIZE indexAddrArray :: ByteArray Int -> Int -> Addr #-}
288 --NO:{-# SPECIALIZE indexFloatArray :: ByteArray Int -> Int -> Float #-}
289 {-# SPECIALIZE indexDoubleArray :: ByteArray Int -> Int -> Double #-}
291 indexCharArray (ByteArray ixs barr#) n
292 = case (index ixs n) of { I# n# ->
293 case indexCharArray# barr# n# of { r# ->
296 indexIntArray (ByteArray ixs barr#) n
297 = case (index ixs n) of { I# n# ->
298 case indexIntArray# barr# n# of { r# ->
301 indexAddrArray (ByteArray ixs barr#) n
302 = case (index ixs n) of { I# n# ->
303 case indexAddrArray# barr# n# of { r# ->
306 indexFloatArray (ByteArray ixs barr#) n
307 = case (index ixs n) of { I# n# ->
308 case indexFloatArray# barr# n# of { r# ->
311 indexDoubleArray (ByteArray ixs barr#) n
312 = case (index ixs n) of { I# n# ->
313 case indexDoubleArray# barr# n# of { r# ->
316 --Indexing off @Addrs@ is similar, and therefore given here.
317 indexCharOffAddr :: Addr -> Int -> Char
318 indexIntOffAddr :: Addr -> Int -> Int
319 indexAddrOffAddr :: Addr -> Int -> Addr
320 indexFloatOffAddr :: Addr -> Int -> Float
321 indexDoubleOffAddr :: Addr -> Int -> Double
323 indexCharOffAddr (A# addr#) n
324 = case n of { I# n# ->
325 case indexCharOffAddr# addr# n# of { r# ->
328 indexIntOffAddr (A# addr#) n
329 = case n of { I# n# ->
330 case indexIntOffAddr# addr# n# of { r# ->
333 indexAddrOffAddr (A# addr#) n
334 = case n of { I# n# ->
335 case indexAddrOffAddr# addr# n# of { r# ->
338 indexFloatOffAddr (A# addr#) n
339 = case n of { I# n# ->
340 case indexFloatOffAddr# addr# n# of { r# ->
343 indexDoubleOffAddr (A# addr#) n
344 = case n of { I# n# ->
345 case indexDoubleOffAddr# addr# n# of { r# ->
348 writeArray :: Ix ix => MutableArray s ix elt -> ix -> elt -> ST s ()
349 writeCharArray :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s ()
350 writeIntArray :: Ix ix => MutableByteArray s ix -> ix -> Int -> ST s ()
351 writeAddrArray :: Ix ix => MutableByteArray s ix -> ix -> Addr -> ST s ()
352 writeFloatArray :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s ()
353 writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s ()
355 {-# SPECIALIZE writeArray :: MutableArray s Int elt -> Int -> elt -> ST s (),
356 MutableArray s IPr elt -> IPr -> elt -> ST s ()
358 {-# SPECIALIZE writeCharArray :: MutableByteArray s Int -> Int -> Char -> ST s () #-}
359 {-# SPECIALIZE writeIntArray :: MutableByteArray s Int -> Int -> Int -> ST s () #-}
360 {-# SPECIALIZE writeAddrArray :: MutableByteArray s Int -> Int -> Addr -> ST s () #-}
361 --NO:{-# SPECIALIZE writeFloatArray :: MutableByteArray s Int -> Int -> Float -> ST s () #-}
362 {-# SPECIALIZE writeDoubleArray :: MutableByteArray s Int -> Int -> Double -> ST s () #-}
364 writeArray (MutableArray ixs arr#) n ele = ST $ \ (S# s#) ->
365 case index ixs n of { I# n# ->
366 case writeArray# arr# n# ele s# of { s2# ->
369 writeCharArray (MutableByteArray ixs barr#) n (C# ele) = ST $ \ (S# s#) ->
370 case (index ixs n) of { I# n# ->
371 case writeCharArray# barr# n# ele s# of { s2# ->
374 writeIntArray (MutableByteArray ixs barr#) n (I# ele) = ST $ \ (S# s#) ->
375 case (index ixs n) of { I# n# ->
376 case writeIntArray# barr# n# ele s# of { s2# ->
379 writeAddrArray (MutableByteArray ixs barr#) n (A# ele) = ST $ \ (S# s#) ->
380 case (index ixs n) of { I# n# ->
381 case writeAddrArray# barr# n# ele s# of { s2# ->
384 writeFloatArray (MutableByteArray ixs barr#) n (F# ele) = ST $ \ (S# s#) ->
385 case (index ixs n) of { I# n# ->
386 case writeFloatArray# barr# n# ele s# of { s2# ->
389 writeDoubleArray (MutableByteArray ixs barr#) n (D# ele) = ST $ \ (S# s#) ->
390 case (index ixs n) of { I# n# ->
391 case writeDoubleArray# barr# n# ele s# of { s2# ->
396 %*********************************************************
398 \subsection{Moving between mutable and immutable}
400 %*********************************************************
403 freezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
404 freezeCharArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
405 freezeIntArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
406 freezeAddrArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
407 freezeFloatArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
408 freezeDoubleArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
410 {-# SPECIALISE freezeArray :: MutableArray s Int elt -> ST s (Array Int elt),
411 MutableArray s IPr elt -> ST s (Array IPr elt)
413 {-# SPECIALISE freezeCharArray :: MutableByteArray s Int -> ST s (ByteArray Int) #-}
415 freezeArray (MutableArray ixs arr#) = ST $ \ (S# s#) ->
416 case rangeSize ixs of { I# n# ->
417 case freeze arr# n# s# of { StateAndArray# s2# frozen# ->
418 (Array ixs frozen#, S# s2#)}}
420 freeze :: MutableArray# s ele -- the thing
421 -> Int# -- size of thing to be frozen
422 -> State# s -- the Universe and everything
423 -> StateAndArray# s ele
426 = case newArray# n# init s# of { StateAndMutableArray# s2# newarr1# ->
427 case copy 0# n# arr# newarr1# s2# of { StateAndMutableArray# s3# newarr2# ->
428 unsafeFreezeArray# newarr2# s3#
431 init = error "freezeArray: element not copied"
434 -> MutableArray# s ele -> MutableArray# s ele
436 -> StateAndMutableArray# s ele
438 copy cur# end# from# to# s#
440 = StateAndMutableArray# s# to#
442 = case readArray# from# cur# s# of { StateAndPtr# s1# ele ->
443 case writeArray# to# cur# ele s1# of { s2# ->
444 copy (cur# +# 1#) end# from# to# s2#
447 freezeCharArray (MutableByteArray ixs arr#) = ST $ \ (S# s#) ->
448 case rangeSize ixs of { I# n# ->
449 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
450 (ByteArray ixs frozen#, S# s2#) }}
452 freeze :: MutableByteArray# s -- the thing
453 -> Int# -- size of thing to be frozen
454 -> State# s -- the Universe and everything
455 -> StateAndByteArray# s
458 = case (newCharArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
459 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
460 unsafeFreezeByteArray# newarr2# s3#
464 -> MutableByteArray# s -> MutableByteArray# s
466 -> StateAndMutableByteArray# s
468 copy cur# end# from# to# s#
470 = StateAndMutableByteArray# s# to#
472 = case (readCharArray# from# cur# s#) of { StateAndChar# s1# ele ->
473 case (writeCharArray# to# cur# ele s1#) of { s2# ->
474 copy (cur# +# 1#) end# from# to# s2#
477 freezeIntArray (MutableByteArray ixs arr#) = ST $ \ (S# s#) ->
478 case rangeSize ixs of { I# n# ->
479 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
480 (ByteArray ixs frozen#, S# s2#) }}
482 freeze :: MutableByteArray# s -- the thing
483 -> Int# -- size of thing to be frozen
484 -> State# s -- the Universe and everything
485 -> StateAndByteArray# s
488 = case (newIntArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
489 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
490 unsafeFreezeByteArray# newarr2# s3#
494 -> MutableByteArray# s -> MutableByteArray# s
496 -> StateAndMutableByteArray# s
498 copy cur# end# from# to# s#
500 = StateAndMutableByteArray# s# to#
502 = case (readIntArray# from# cur# s#) of { StateAndInt# s1# ele ->
503 case (writeIntArray# to# cur# ele s1#) of { s2# ->
504 copy (cur# +# 1#) end# from# to# s2#
507 freezeAddrArray (MutableByteArray ixs arr#) = ST $ \ (S# s#) ->
508 case rangeSize ixs of { I# n# ->
509 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
510 (ByteArray ixs frozen#, S# s2#) }}
512 freeze :: MutableByteArray# s -- the thing
513 -> Int# -- size of thing to be frozen
514 -> State# s -- the Universe and everything
515 -> StateAndByteArray# s
518 = case (newAddrArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
519 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
520 unsafeFreezeByteArray# newarr2# s3#
524 -> MutableByteArray# s -> MutableByteArray# s
526 -> StateAndMutableByteArray# s
528 copy cur# end# from# to# s#
530 = StateAndMutableByteArray# s# to#
532 = case (readAddrArray# from# cur# s#) of { StateAndAddr# s1# ele ->
533 case (writeAddrArray# to# cur# ele s1#) of { s2# ->
534 copy (cur# +# 1#) end# from# to# s2#
537 freezeFloatArray (MutableByteArray ixs arr#) = ST $ \ (S# s#) ->
538 case rangeSize ixs of { I# n# ->
539 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
540 (ByteArray ixs frozen#, S# s2#) }}
542 freeze :: MutableByteArray# s -- the thing
543 -> Int# -- size of thing to be frozen
544 -> State# s -- the Universe and everything
545 -> StateAndByteArray# s
548 = case (newFloatArray# end# s#) of { StateAndMutableByteArray# s2# newarr1# ->
549 case copy 0# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
550 unsafeFreezeByteArray# newarr2# s3#
554 -> MutableByteArray# s -> MutableByteArray# s
556 -> StateAndMutableByteArray# s
558 copy cur# from# to# s#
560 = StateAndMutableByteArray# s# to#
562 = case (readFloatArray# from# cur# s#) of { StateAndFloat# s1# ele ->
563 case (writeFloatArray# to# cur# ele s1#) of { s2# ->
564 copy (cur# +# 1#) from# to# s2#
567 freezeDoubleArray (MutableByteArray ixs arr#) = ST $ \ (S# s#) ->
568 case rangeSize ixs of { I# n# ->
569 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
570 (ByteArray ixs frozen#, S# s2#) }}
572 freeze :: MutableByteArray# s -- the thing
573 -> Int# -- size of thing to be frozen
574 -> State# s -- the Universe and everything
575 -> StateAndByteArray# s
578 = case (newDoubleArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
579 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
580 unsafeFreezeByteArray# newarr2# s3#
584 -> MutableByteArray# s -> MutableByteArray# s
586 -> StateAndMutableByteArray# s
588 copy cur# end# from# to# s#
590 = StateAndMutableByteArray# s# to#
592 = case (readDoubleArray# from# cur# s#) of { StateAndDouble# s1# ele ->
593 case (writeDoubleArray# to# cur# ele s1#) of { s2# ->
594 copy (cur# +# 1#) end# from# to# s2#
597 unsafeFreezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
598 unsafeFreezeByteArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
600 {-# SPECIALIZE unsafeFreezeByteArray :: MutableByteArray s Int -> ST s (ByteArray Int)
603 unsafeFreezeArray (MutableArray ixs arr#) = ST $ \ (S# s#) ->
604 case unsafeFreezeArray# arr# s# of { StateAndArray# s2# frozen# ->
605 (Array ixs frozen#, S# s2#) }
607 unsafeFreezeByteArray (MutableByteArray ixs arr#) = ST $ \ (S# s#) ->
608 case unsafeFreezeByteArray# arr# s# of { StateAndByteArray# s2# frozen# ->
609 (ByteArray ixs frozen#, S# s2#) }
612 --This takes a immutable array, and copies it into a mutable array, in a
615 {-# SPECIALISE thawArray :: Array Int elt -> ST s (MutableArray s Int elt),
616 Array IPr elt -> ST s (MutableArray s IPr elt)
619 thawArray :: Ix ix => Array ix elt -> ST s (MutableArray s ix elt)
620 thawArray (Array ixs arr#) = ST $ \ (S# s#) ->
621 case rangeSize ixs of { I# n# ->
622 case thaw arr# n# s# of { StateAndMutableArray# s2# thawed# ->
623 (MutableArray ixs thawed#, S# s2#)}}
625 thaw :: Array# ele -- the thing
626 -> Int# -- size of thing to be thawed
627 -> State# s -- the Universe and everything
628 -> StateAndMutableArray# s ele
631 = case newArray# n# init s# of { StateAndMutableArray# s2# newarr1# ->
632 copy 0# n# arr# newarr1# s2# }
634 init = error "thawArray: element not copied"
638 -> MutableArray# s ele
640 -> StateAndMutableArray# s ele
642 copy cur# end# from# to# s#
644 = StateAndMutableArray# s# to#
646 = case indexArray# from# cur# of { Lift ele ->
647 case writeArray# to# cur# ele s# of { s1# ->
648 copy (cur# +# 1#) end# from# to# s1#
652 %*********************************************************
654 \subsection{Ghastly return types}
656 %*********************************************************
659 data StateAndArray# s elt = StateAndArray# (State# s) (Array# elt)
660 data StateAndMutableArray# s elt = StateAndMutableArray# (State# s) (MutableArray# s elt)
661 data StateAndByteArray# s = StateAndByteArray# (State# s) ByteArray#
662 data StateAndMutableByteArray# s = StateAndMutableByteArray# (State# s) (MutableByteArray# s)