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 )
25 {-# GENERATE_SPECS array a{~,Int,IPr} b{} #-}
26 array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
28 {-# GENERATE_SPECS (!) a{~,Int,IPr} b{} #-}
29 (!) :: (Ix a) => Array a b -> a -> b
31 bounds :: (Ix a) => Array a b -> (a,a)
33 {-# GENERATE_SPECS (//) a{~,Int,IPr} b{} #-}
34 (//) :: (Ix a) => Array a b -> [(a,b)] -> Array a b
36 {-# GENERATE_SPECS accum a{~,Int,IPr} b{} c{} #-}
37 accum :: (Ix a) => (b -> c -> b) -> Array a b -> [(a,c)] -> Array a b
39 {-# GENERATE_SPECS accumArray a{~,Int,IPr} b{} c{} #-}
40 accumArray :: (Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b
44 %*********************************************************
46 \subsection{The @Array@ types}
48 %*********************************************************
53 data Ix ix => Array ix elt = Array (ix,ix) (Array# elt)
54 data Ix ix => ByteArray ix = ByteArray (ix,ix) ByteArray#
55 data Ix ix => MutableArray s ix elt = MutableArray (ix,ix) (MutableArray# s elt)
56 data Ix ix => MutableByteArray s ix = MutableByteArray (ix,ix) (MutableByteArray# s)
58 -- A one-element mutable array:
59 type MutableVar s a = MutableArray s Int a
63 %*********************************************************
65 \subsection{Operations on immutable arrays}
67 %*********************************************************
69 "array", "!" and "bounds" are basic; the rest can be defined in terms of them
72 bounds (Array b _) = b
74 (Array bounds arr#) ! i
75 = let n# = case (index bounds i) of { I# x -> x } -- index fails if out of range
77 case (indexArray# arr# n#) of
80 #ifdef USE_FOLDR_BUILD
83 array ixs@(ix_start, ix_end) ivs =
85 case (newArray ixs arrEleBottom) of { ST new_array_thing ->
86 case (new_array_thing s) of { (arr@(MutableArray _ arr#),s) ->
88 fill_one_in (S# s#) (i, v)
89 = case index ixs i of { I# n# ->
90 case writeArray# arr# n# v s# of { s2# ->
93 case (foldl fill_one_in s ivs) of { s@(S# _) ->
94 case (freezeArray arr) of { ST freeze_array_thing ->
95 freeze_array_thing s }}}})
97 arrEleBottom = error "(Array.!): undefined array element"
99 fill_it_in :: Ix ix => MutableArray s ix elt -> [(ix, elt)] -> ST s ()
101 = foldr fill_one_in (returnST ()) lst
102 where -- **** STRICT **** (but that's OK...)
103 fill_one_in (i, v) rst
104 = writeArray arr i v `seqST` rst
106 -----------------------------------------------------------------------
107 -- these also go better with magic: (//), accum, accumArray
111 -- copy the old array:
112 thawArray old_array `thenST` \ arr ->
113 -- now write the new elements into the new array:
114 fill_it_in arr ivs `seqST`
118 bottom = error "(Array.//): error in copying old array\n"
120 zap_with_f :: Ix ix => (elt -> elt2 -> elt) -> MutableArray s ix elt -> [(ix,elt2)] -> ST s ()
121 -- zap_with_f: reads an elem out first, then uses "f" on that and the new value
124 = foldr zap_one (returnST ()) lst
126 zap_one (i, new_v) rst
127 = readArray arr i `thenST` \ old_v ->
128 writeArray arr i (f old_v new_v) `seqST`
131 accum f old_array ivs
133 -- copy the old array:
134 thawArray old_array `thenST` \ arr ->
136 -- now zap the elements in question with "f":
137 zap_with_f f arr ivs >>
141 bottom = error "Array.accum: error in copying old array\n"
143 accumArray f zero ixs ivs
145 newArray ixs zero >>= \ arr# ->
146 zap_with_f f arr# ivs >>
152 %*********************************************************
154 \subsection{Operations on mutable arrays}
156 %*********************************************************
158 Idle ADR question: What's the tradeoff here between flattening these
159 datatypes into @MutableArray ix ix (MutableArray# s elt)@ and using
160 it as is? As I see it, the former uses slightly less heap and
161 provides faster access to the individual parts of the bounds while the
162 code used has the benefit of providing a ready-made @(lo, hi)@ pair as
163 required by many array-related functions. Which wins? Is the
164 difference significant (probably not).
166 Idle AJG answer: When I looked at the outputted code (though it was 2
167 years ago) it seems like you often needed the tuple, and we build
168 it frequently. Now we've got the overloading specialiser things
169 might be different, though.
172 newArray :: Ix ix => (ix,ix) -> elt -> ST s (MutableArray s ix elt)
173 newCharArray, newIntArray, newAddrArray, newFloatArray, newDoubleArray
174 :: Ix ix => (ix,ix) -> ST s (MutableByteArray s ix)
176 {-# SPECIALIZE newArray :: IPr -> elt -> ST s (MutableArray s Int elt),
177 (IPr,IPr) -> elt -> ST s (MutableArray s IPr elt)
179 {-# SPECIALIZE newCharArray :: IPr -> ST s (MutableByteArray s Int) #-}
180 {-# SPECIALIZE newIntArray :: IPr -> ST s (MutableByteArray s Int) #-}
181 {-# SPECIALIZE newAddrArray :: IPr -> ST s (MutableByteArray s Int) #-}
182 {-# SPECIALIZE newFloatArray :: IPr -> ST s (MutableByteArray s Int) #-}
183 {-# SPECIALIZE newDoubleArray :: IPr -> ST s (MutableByteArray s Int) #-}
185 newArray ixs@(ix_start, ix_end) init = ST $ \ (S# s#) ->
186 let n# = case (if null (range ixs)
188 else (index ixs ix_end) + 1) of { I# x -> x }
189 -- size is one bigger than index of last elem
191 case (newArray# n# init s#) of { StateAndMutableArray# s2# arr# ->
192 (MutableArray ixs arr#, S# s2#)}
194 newCharArray ixs@(ix_start, ix_end) = ST $ \ (S# s#) ->
195 let n# = case (if null (range ixs)
197 else ((index ixs ix_end) + 1)) of { I# x -> x }
199 case (newCharArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
200 (MutableByteArray ixs barr#, S# s2#)}
202 newIntArray ixs@(ix_start, ix_end) = ST $ \ (S# s#) ->
203 let n# = case (if null (range ixs)
205 else ((index ixs ix_end) + 1)) of { I# x -> x }
207 case (newIntArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
208 (MutableByteArray ixs barr#, S# s2#)}
210 newAddrArray ixs@(ix_start, ix_end) = ST $ \ (S# s#) ->
211 let n# = case (if null (range ixs)
213 else ((index ixs ix_end) + 1)) of { I# x -> x }
215 case (newAddrArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
216 (MutableByteArray ixs barr#, S# s2#)}
218 newFloatArray ixs@(ix_start, ix_end) = ST $ \ (S# s#) ->
219 let n# = case (if null (range ixs)
221 else ((index ixs ix_end) + 1)) of { I# x -> x }
223 case (newFloatArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
224 (MutableByteArray ixs barr#, S# s2#)}
226 newDoubleArray ixs@(ix_start, ix_end) = ST $ \ (S# s#) ->
227 let n# = case (if null (range ixs)
229 else ((index ixs ix_end) + 1)) of { I# x -> x }
231 case (newDoubleArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
232 (MutableByteArray ixs barr#, S# s2#)}
234 boundsOfArray :: Ix ix => MutableArray s ix elt -> (ix, ix)
235 boundsOfByteArray :: Ix ix => MutableByteArray s ix -> (ix, ix)
237 {-# SPECIALIZE boundsOfArray :: MutableArray s Int elt -> IPr #-}
238 {-# SPECIALIZE boundsOfByteArray :: MutableByteArray s Int -> IPr #-}
240 boundsOfArray (MutableArray ixs _) = ixs
241 boundsOfByteArray (MutableByteArray ixs _) = ixs
243 readArray :: Ix ix => MutableArray s ix elt -> ix -> ST s elt
245 readCharArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Char
246 readIntArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Int
247 readAddrArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Addr
248 readFloatArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Float
249 readDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> ST s Double
251 {-# SPECIALIZE readArray :: MutableArray s Int elt -> Int -> ST s elt,
252 MutableArray s IPr elt -> IPr -> ST s elt
254 {-# SPECIALIZE readCharArray :: MutableByteArray s Int -> Int -> ST s Char #-}
255 {-# SPECIALIZE readIntArray :: MutableByteArray s Int -> Int -> ST s Int #-}
256 {-# SPECIALIZE readAddrArray :: MutableByteArray s Int -> Int -> ST s Addr #-}
257 --NO:{-# SPECIALIZE readFloatArray :: MutableByteArray s Int -> Int -> ST s Float #-}
258 {-# SPECIALIZE readDoubleArray :: MutableByteArray s Int -> Int -> ST s Double #-}
260 readArray (MutableArray ixs arr#) n = ST $ \ (S# s#) ->
261 case (index ixs n) of { I# n# ->
262 case readArray# arr# n# s# of { StateAndPtr# s2# r ->
265 readCharArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
266 case (index ixs n) of { I# n# ->
267 case readCharArray# barr# n# s# of { StateAndChar# s2# r# ->
270 readIntArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
271 case (index ixs n) of { I# n# ->
272 case readIntArray# barr# n# s# of { StateAndInt# s2# r# ->
275 readAddrArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
276 case (index ixs n) of { I# n# ->
277 case readAddrArray# barr# n# s# of { StateAndAddr# s2# r# ->
280 readFloatArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
281 case (index ixs n) of { I# n# ->
282 case readFloatArray# barr# n# s# of { StateAndFloat# s2# r# ->
285 readDoubleArray (MutableByteArray ixs barr#) n = ST $ \ (S# s#) ->
286 case (index ixs n) of { I# n# ->
287 case readDoubleArray# barr# n# s# of { StateAndDouble# s2# r# ->
290 --Indexing of ordinary @Arrays@ is standard Haskell and isn't defined here.
291 indexCharArray :: Ix ix => ByteArray ix -> ix -> Char
292 indexIntArray :: Ix ix => ByteArray ix -> ix -> Int
293 indexAddrArray :: Ix ix => ByteArray ix -> ix -> Addr
294 indexFloatArray :: Ix ix => ByteArray ix -> ix -> Float
295 indexDoubleArray :: Ix ix => ByteArray ix -> ix -> Double
297 {-# SPECIALIZE indexCharArray :: ByteArray Int -> Int -> Char #-}
298 {-# SPECIALIZE indexIntArray :: ByteArray Int -> Int -> Int #-}
299 {-# SPECIALIZE indexAddrArray :: ByteArray Int -> Int -> Addr #-}
300 --NO:{-# SPECIALIZE indexFloatArray :: ByteArray Int -> Int -> Float #-}
301 {-# SPECIALIZE indexDoubleArray :: ByteArray Int -> Int -> Double #-}
303 indexCharArray (ByteArray ixs barr#) n
304 = case (index ixs n) of { I# n# ->
305 case indexCharArray# barr# n# of { r# ->
308 indexIntArray (ByteArray ixs barr#) n
309 = case (index ixs n) of { I# n# ->
310 case indexIntArray# barr# n# of { r# ->
313 indexAddrArray (ByteArray ixs barr#) n
314 = case (index ixs n) of { I# n# ->
315 case indexAddrArray# barr# n# of { r# ->
318 indexFloatArray (ByteArray ixs barr#) n
319 = case (index ixs n) of { I# n# ->
320 case indexFloatArray# barr# n# of { r# ->
323 indexDoubleArray (ByteArray ixs barr#) n
324 = case (index ixs n) of { I# n# ->
325 case indexDoubleArray# barr# n# of { r# ->
328 --Indexing off @Addrs@ is similar, and therefore given here.
329 indexCharOffAddr :: Addr -> Int -> Char
330 indexIntOffAddr :: Addr -> Int -> Int
331 indexAddrOffAddr :: Addr -> Int -> Addr
332 indexFloatOffAddr :: Addr -> Int -> Float
333 indexDoubleOffAddr :: Addr -> Int -> Double
335 indexCharOffAddr (A# addr#) n
336 = case n of { I# n# ->
337 case indexCharOffAddr# addr# n# of { r# ->
340 indexIntOffAddr (A# addr#) n
341 = case n of { I# n# ->
342 case indexIntOffAddr# addr# n# of { r# ->
345 indexAddrOffAddr (A# addr#) n
346 = case n of { I# n# ->
347 case indexAddrOffAddr# addr# n# of { r# ->
350 indexFloatOffAddr (A# addr#) n
351 = case n of { I# n# ->
352 case indexFloatOffAddr# addr# n# of { r# ->
355 indexDoubleOffAddr (A# addr#) n
356 = case n of { I# n# ->
357 case indexDoubleOffAddr# addr# n# of { r# ->
360 writeArray :: Ix ix => MutableArray s ix elt -> ix -> elt -> ST s ()
361 writeCharArray :: Ix ix => MutableByteArray s ix -> ix -> Char -> ST s ()
362 writeIntArray :: Ix ix => MutableByteArray s ix -> ix -> Int -> ST s ()
363 writeAddrArray :: Ix ix => MutableByteArray s ix -> ix -> Addr -> ST s ()
364 writeFloatArray :: Ix ix => MutableByteArray s ix -> ix -> Float -> ST s ()
365 writeDoubleArray :: Ix ix => MutableByteArray s ix -> ix -> Double -> ST s ()
367 {-# SPECIALIZE writeArray :: MutableArray s Int elt -> Int -> elt -> ST s (),
368 MutableArray s IPr elt -> IPr -> elt -> ST s ()
370 {-# SPECIALIZE writeCharArray :: MutableByteArray s Int -> Int -> Char -> ST s () #-}
371 {-# SPECIALIZE writeIntArray :: MutableByteArray s Int -> Int -> Int -> ST s () #-}
372 {-# SPECIALIZE writeAddrArray :: MutableByteArray s Int -> Int -> Addr -> ST s () #-}
373 --NO:{-# SPECIALIZE writeFloatArray :: MutableByteArray s Int -> Int -> Float -> ST s () #-}
374 {-# SPECIALIZE writeDoubleArray :: MutableByteArray s Int -> Int -> Double -> ST s () #-}
376 writeArray (MutableArray ixs arr#) n ele = ST $ \ (S# s#) ->
377 case index ixs n of { I# n# ->
378 case writeArray# arr# n# ele s# of { s2# ->
381 writeCharArray (MutableByteArray ixs barr#) n (C# ele) = ST $ \ (S# s#) ->
382 case (index ixs n) of { I# n# ->
383 case writeCharArray# barr# n# ele s# of { s2# ->
386 writeIntArray (MutableByteArray ixs barr#) n (I# ele) = ST $ \ (S# s#) ->
387 case (index ixs n) of { I# n# ->
388 case writeIntArray# barr# n# ele s# of { s2# ->
391 writeAddrArray (MutableByteArray ixs barr#) n (A# ele) = ST $ \ (S# s#) ->
392 case (index ixs n) of { I# n# ->
393 case writeAddrArray# barr# n# ele s# of { s2# ->
396 writeFloatArray (MutableByteArray ixs barr#) n (F# ele) = ST $ \ (S# s#) ->
397 case (index ixs n) of { I# n# ->
398 case writeFloatArray# barr# n# ele s# of { s2# ->
401 writeDoubleArray (MutableByteArray ixs barr#) n (D# ele) = ST $ \ (S# s#) ->
402 case (index ixs n) of { I# n# ->
403 case writeDoubleArray# barr# n# ele s# of { s2# ->
408 %*********************************************************
410 \subsection{Moving between mutable and immutable}
412 %*********************************************************
415 freezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
416 freezeCharArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
417 freezeIntArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
418 freezeAddrArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
419 freezeFloatArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
420 freezeDoubleArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
422 {-# SPECIALISE freezeArray :: MutableArray s Int elt -> ST s (Array Int elt),
423 MutableArray s IPr elt -> ST s (Array IPr elt)
425 {-# SPECIALISE freezeCharArray :: MutableByteArray s Int -> ST s (ByteArray Int) #-}
427 freezeArray (MutableArray ixs@(ix_start, ix_end) arr#) = ST $ \ (S# s#) ->
428 let n# = case (if null (range ixs)
430 else (index ixs ix_end) + 1) of { I# x -> x }
432 case freeze arr# n# s# of { StateAndArray# s2# frozen# ->
433 (Array ixs frozen#, S# s2#)}
435 freeze :: MutableArray# s ele -- the thing
436 -> Int# -- size of thing to be frozen
437 -> State# s -- the Universe and everything
438 -> StateAndArray# s ele
441 = case newArray# n# init s# of { StateAndMutableArray# s2# newarr1# ->
442 case copy 0# n# arr# newarr1# s2# of { StateAndMutableArray# s3# newarr2# ->
443 unsafeFreezeArray# newarr2# s3#
446 init = error "freezeArray: element not copied"
449 -> MutableArray# s ele -> MutableArray# s ele
451 -> StateAndMutableArray# s ele
453 copy cur# end# from# to# s#
455 = StateAndMutableArray# s# to#
457 = case readArray# from# cur# s# of { StateAndPtr# s1# ele ->
458 case writeArray# to# cur# ele s1# of { s2# ->
459 copy (cur# +# 1#) end# from# to# s2#
462 freezeCharArray (MutableByteArray ixs@(ix_start, ix_end) arr#) = ST $ \ (S# s#) ->
463 let n# = case (if null (range ixs)
465 else ((index ixs ix_end) + 1)) of { I# x -> x }
467 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
468 (ByteArray ixs frozen#, S# s2#) }
470 freeze :: MutableByteArray# s -- the thing
471 -> Int# -- size of thing to be frozen
472 -> State# s -- the Universe and everything
473 -> StateAndByteArray# s
476 = case (newCharArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
477 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
478 unsafeFreezeByteArray# newarr2# s3#
482 -> MutableByteArray# s -> MutableByteArray# s
484 -> StateAndMutableByteArray# s
486 copy cur# end# from# to# s#
488 = StateAndMutableByteArray# s# to#
490 = case (readCharArray# from# cur# s#) of { StateAndChar# s1# ele ->
491 case (writeCharArray# to# cur# ele s1#) of { s2# ->
492 copy (cur# +# 1#) end# from# to# s2#
495 freezeIntArray (MutableByteArray ixs@(ix_start, ix_end) arr#) = ST $ \ (S# s#) ->
496 let n# = case (if null (range ixs)
498 else ((index ixs ix_end) + 1)) of { I# x -> x }
500 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
501 (ByteArray ixs frozen#, S# s2#) }
503 freeze :: MutableByteArray# s -- the thing
504 -> Int# -- size of thing to be frozen
505 -> State# s -- the Universe and everything
506 -> StateAndByteArray# s
509 = case (newIntArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
510 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
511 unsafeFreezeByteArray# newarr2# s3#
515 -> MutableByteArray# s -> MutableByteArray# s
517 -> StateAndMutableByteArray# s
519 copy cur# end# from# to# s#
521 = StateAndMutableByteArray# s# to#
523 = case (readIntArray# from# cur# s#) of { StateAndInt# s1# ele ->
524 case (writeIntArray# to# cur# ele s1#) of { s2# ->
525 copy (cur# +# 1#) end# from# to# s2#
528 freezeAddrArray (MutableByteArray ixs@(ix_start, ix_end) arr#) = ST $ \ (S# s#) ->
529 let n# = case (if null (range ixs)
531 else ((index ixs ix_end) + 1)) of { I# x -> x }
533 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
534 (ByteArray ixs frozen#, S# s2#) }
536 freeze :: MutableByteArray# s -- the thing
537 -> Int# -- size of thing to be frozen
538 -> State# s -- the Universe and everything
539 -> StateAndByteArray# s
542 = case (newAddrArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
543 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
544 unsafeFreezeByteArray# newarr2# s3#
548 -> MutableByteArray# s -> MutableByteArray# s
550 -> StateAndMutableByteArray# s
552 copy cur# end# from# to# s#
554 = StateAndMutableByteArray# s# to#
556 = case (readAddrArray# from# cur# s#) of { StateAndAddr# s1# ele ->
557 case (writeAddrArray# to# cur# ele s1#) of { s2# ->
558 copy (cur# +# 1#) end# from# to# s2#
561 freezeFloatArray (MutableByteArray ixs@(ix_start, ix_end) arr#) = ST $ \ (S# s#) ->
562 let n# = case (if null (range ixs)
564 else ((index ixs ix_end) + 1)) of { I# x -> x }
566 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
567 (ByteArray ixs frozen#, S# s2#) }
569 freeze :: MutableByteArray# s -- the thing
570 -> Int# -- size of thing to be frozen
571 -> State# s -- the Universe and everything
572 -> StateAndByteArray# s
575 = case (newFloatArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
576 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
577 unsafeFreezeByteArray# newarr2# s3#
581 -> MutableByteArray# s -> MutableByteArray# s
583 -> StateAndMutableByteArray# s
585 copy cur# end# from# to# s#
587 = StateAndMutableByteArray# s# to#
589 = case (readFloatArray# from# cur# s#) of { StateAndFloat# s1# ele ->
590 case (writeFloatArray# to# cur# ele s1#) of { s2# ->
591 copy (cur# +# 1#) end# from# to# s2#
594 freezeDoubleArray (MutableByteArray ixs@(ix_start, ix_end) arr#) = ST $ \ (S# s#) ->
595 let n# = case (if null (range ixs)
597 else ((index ixs ix_end) + 1)) of { I# x -> x }
599 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
600 (ByteArray ixs frozen#, S# s2#) }
602 freeze :: MutableByteArray# s -- the thing
603 -> Int# -- size of thing to be frozen
604 -> State# s -- the Universe and everything
605 -> StateAndByteArray# s
608 = case (newDoubleArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
609 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
610 unsafeFreezeByteArray# newarr2# s3#
614 -> MutableByteArray# s -> MutableByteArray# s
616 -> StateAndMutableByteArray# s
618 copy cur# end# from# to# s#
620 = StateAndMutableByteArray# s# to#
622 = case (readDoubleArray# from# cur# s#) of { StateAndDouble# s1# ele ->
623 case (writeDoubleArray# to# cur# ele s1#) of { s2# ->
624 copy (cur# +# 1#) end# from# to# s2#
627 unsafeFreezeArray :: Ix ix => MutableArray s ix elt -> ST s (Array ix elt)
628 unsafeFreezeByteArray :: Ix ix => MutableByteArray s ix -> ST s (ByteArray ix)
630 {-# SPECIALIZE unsafeFreezeByteArray :: MutableByteArray s Int -> ST s (ByteArray Int)
633 unsafeFreezeArray (MutableArray ixs arr#) = ST $ \ (S# s#) ->
634 case unsafeFreezeArray# arr# s# of { StateAndArray# s2# frozen# ->
635 (Array ixs frozen#, S# s2#) }
637 unsafeFreezeByteArray (MutableByteArray ixs arr#) = ST $ \ (S# s#) ->
638 case unsafeFreezeByteArray# arr# s# of { StateAndByteArray# s2# frozen# ->
639 (ByteArray ixs frozen#, S# s2#) }
642 --This takes a immutable array, and copies it into a mutable array, in a
645 {-# SPECIALISE thawArray :: Array Int elt -> ST s (MutableArray s Int elt),
646 Array IPr elt -> ST s (MutableArray s IPr elt)
649 thawArray :: Ix ix => Array ix elt -> ST s (MutableArray s ix elt)
650 thawArray (Array ixs@(ix_start, ix_end) arr#) = ST $ \ (S# s#) ->
651 let n# = case (if null (range ixs)
653 else (index ixs ix_end) + 1) of { I# x -> x }
655 case thaw arr# n# s# of { StateAndMutableArray# s2# thawed# ->
656 (MutableArray ixs thawed#, S# s2#)}
658 thaw :: Array# ele -- the thing
659 -> Int# -- size of thing to be thawed
660 -> State# s -- the Universe and everything
661 -> StateAndMutableArray# s ele
664 = case newArray# n# init s# of { StateAndMutableArray# s2# newarr1# ->
665 copy 0# n# arr# newarr1# s2# }
667 init = error "thawArray: element not copied"
671 -> MutableArray# s ele
673 -> StateAndMutableArray# s ele
675 copy cur# end# from# to# s#
677 = StateAndMutableArray# s# to#
679 = case indexArray# from# cur# of { Lift ele ->
680 case writeArray# to# cur# ele s# of { s1# ->
681 copy (cur# +# 1#) end# from# to# s1#
685 %*********************************************************
687 \subsection{Ghastly return types}
689 %*********************************************************
692 data StateAndArray# s elt = StateAndArray# (State# s) (Array# elt)
693 data StateAndMutableArray# s elt = StateAndMutableArray# (State# s) (MutableArray# s elt)
694 data StateAndByteArray# s = StateAndByteArray# (State# s) ByteArray#
695 data StateAndMutableByteArray# s = StateAndMutableByteArray# (State# s) (MutableByteArray# s)