2 % (c) The AQUA Project, Glasgow University, 1994
4 \section[PreludeGlaST]{Basic ``state transformer'' monad, mutable arrays and variables}
6 See state-interface.verb, from which this is taken directly.
9 #include "../../includes/platform.h"
10 #include "../../includes/GhcConstants.h"
15 _MutableByteArray(..),
16 ST(..), -- it's a known GHC infelicity that synonyms must
17 MutableVar(..), -- be listed separately.
19 --!! because this interface is now the "everything state-transformer"ish
20 --!! interface, here is all the PreludePrimIO stuff
22 -- PrimIO(..): no, the compiler already knows about it
32 unsafeInterleavePrimIO,
35 -- all the Stdio stuff (this is how you get to it)
37 fclose, fdopen, fflush, fopen, fread, freopen,
40 -- backward compatibility -- don't use!
46 --!! end of PreludePrimIO
48 _ByteArray(..), Array(..) -- reexport *unabstractly*
51 import PreludePrimIO (
60 unsafeInterleavePrimIO,
73 import List ( map, null, foldr, (++) )
74 import PS ( _PackedString, _unpackPS )
75 import TyArray ( Array(..), _ByteArray(..) )
79 infixr 9 `thenST`, `thenStrictlyST`, `seqST`, `seqStrictlyST`
84 %************************************************************************
86 \subsection[PreludeGlaST-ST-monad]{The state-transformer proper}
88 %************************************************************************
91 --BUILT-IN: type _ST s a -- State transformer
93 type ST s a = _ST s a -- so you don't need -fglasgow-exts
95 {-# INLINE returnST #-}
96 {-# INLINE returnStrictlyST #-}
97 {-# INLINE thenStrictlyST #-}
98 {-# INLINE seqStrictlyST #-}
100 returnST :: a -> _ST s a
101 returnST a s = (a, s)
103 thenST :: _ST s a -> (a -> _ST s b) -> _ST s b
104 thenST m k s = let (r,new_s) = m s
108 seqST :: _ST s a -> _ST s b -> _ST s b
109 seqST m1 m2 = m1 `thenST` (\ _ -> m2)
112 {-# GENERATE_SPECS returnStrictlyST a #-}
113 returnStrictlyST :: a -> _ST s a
115 {-# GENERATE_SPECS thenStrictlyST a b #-}
116 thenStrictlyST :: _ST s a -> (a -> _ST s b) -> _ST s b
118 {-# GENERATE_SPECS seqStrictlyST a b #-}
119 seqStrictlyST :: _ST s a -> _ST s b -> _ST s b
122 returnStrictlyST a s@(S# _) = (a, s)
124 thenStrictlyST m k s -- @(S# _) Omitted SLPJ [May95] no need to evaluate the state
125 = case (m s) of { (r, new_s) ->
128 seqStrictlyST m k s -- @(S# _) Omitted SLPJ [May95] no need to evaluate the state
129 = case (m s) of { (_, new_s) ->
133 -- BUILT-IN: _runST (see Builtin.hs)
135 unsafeInterleaveST :: _ST s a -> _ST s a -- ToDo: put in state-interface.tex
136 unsafeInterleaveST m s
143 fixST :: (a -> _ST s a) -> _ST s a
144 fixST k s = let ans = k r s
149 listST :: [_ST s a] -> _ST s [a]
150 listST [] = returnST []
151 listST (m:ms) = m `thenST` \ x ->
152 listST ms `thenST` \ xs ->
155 mapST :: (a -> _ST s b) -> [a] -> _ST s [b]
156 mapST f ms = listST (map f ms)
158 mapAndUnzipST :: (a -> _ST s (b,c)) -> [a] -> _ST s ([b],[c])
159 mapAndUnzipST f [] = returnST ([], [])
160 mapAndUnzipST f (m:ms)
161 = f m `thenST` \ ( r1, r2) ->
162 mapAndUnzipST f ms `thenST` \ (rs1, rs2) ->
163 returnST (r1:rs1, r2:rs2)
165 forkST :: ST s a -> ST s a
167 #ifndef __CONCURRENT_HASKELL__
173 (r, new_s) = action s
175 new_s `_fork_` (r, s)
177 _fork_ x y = case (fork# x) of { 0# -> parError#; _ -> y }
179 #endif {- concurrent -}
181 forkPrimIO :: PrimIO a -> PrimIO a
185 %************************************************************************
187 \subsection[PreludeGlaST-arrays]{Mutable arrays}
189 %************************************************************************
191 Idle ADR question: What's the tradeoff here between flattening these
192 datatypes into @_MutableArray ix ix (MutableArray# s elt)@ and using
193 it as is? As I see it, the former uses slightly less heap and
194 provides faster access to the individual parts of the bounds while the
195 code used has the benefit of providing a ready-made @(lo, hi)@ pair as
196 required by many array-related functions. Which wins? Is the
197 difference significant (probably not).
199 Idle AJG answer: When I looked at the outputted code (though it was 2
200 years ago) it seems like you often needed the tuple, and we build
201 it frequently. Now we've got the overloading specialiser things
202 might be different, though.
205 data _MutableArray s ix elt = _MutableArray (ix,ix) (MutableArray# s elt)
206 data _MutableByteArray s ix = _MutableByteArray (ix,ix) (MutableByteArray# s)
208 instance _CCallable (_MutableByteArray s ix)
212 newArray :: Ix ix => (ix,ix) -> elt -> _ST s (_MutableArray s ix elt)
213 newCharArray, newIntArray, newAddrArray, newFloatArray, newDoubleArray
214 :: Ix ix => (ix,ix) -> _ST s (_MutableByteArray s ix)
216 {-# SPECIALIZE newArray :: IPr -> elt -> _ST s (_MutableArray s Int elt),
217 (IPr,IPr) -> elt -> _ST s (_MutableArray s IPr elt)
219 {-# SPECIALIZE newCharArray :: IPr -> _ST s (_MutableByteArray s Int) #-}
220 {-# SPECIALIZE newIntArray :: IPr -> _ST s (_MutableByteArray s Int) #-}
221 {-# SPECIALIZE newAddrArray :: IPr -> _ST s (_MutableByteArray s Int) #-}
222 {-# SPECIALIZE newFloatArray :: IPr -> _ST s (_MutableByteArray s Int) #-}
223 {-# SPECIALIZE newDoubleArray :: IPr -> _ST s (_MutableByteArray s Int) #-}
225 newArray ixs@(ix_start, ix_end) init (S# s#)
226 = let n# = case (if null (range ixs)
228 else (index ixs ix_end) + 1) of { I# x -> x }
229 -- size is one bigger than index of last elem
231 case (newArray# n# init s#) of { StateAndMutableArray# s2# arr# ->
232 (_MutableArray ixs arr#, S# s2#)}
234 newCharArray ixs@(ix_start, ix_end) (S# s#)
235 = let n# = case (if null (range ixs)
237 else ((index ixs ix_end) + 1)) of { I# x -> x }
239 case (newCharArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
240 (_MutableByteArray ixs barr#, S# s2#)}
242 newIntArray ixs@(ix_start, ix_end) (S# s#)
243 = let n# = case (if null (range ixs)
245 else ((index ixs ix_end) + 1)) of { I# x -> x }
247 case (newIntArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
248 (_MutableByteArray ixs barr#, S# s2#)}
250 newAddrArray ixs@(ix_start, ix_end) (S# s#)
251 = let n# = case (if null (range ixs)
253 else ((index ixs ix_end) + 1)) of { I# x -> x }
255 case (newAddrArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
256 (_MutableByteArray ixs barr#, S# s2#)}
258 newFloatArray ixs@(ix_start, ix_end) (S# s#)
259 = let n# = case (if null (range ixs)
261 else ((index ixs ix_end) + 1)) of { I# x -> x }
263 case (newFloatArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
264 (_MutableByteArray ixs barr#, S# s2#)}
266 newDoubleArray ixs@(ix_start, ix_end) (S# s#)
267 = let n# = case (if null (range ixs)
269 else ((index ixs ix_end) + 1)) of { I# x -> x }
271 -- trace ("newDoubleArray:"++(show (I# n#))) (
272 case (newDoubleArray# n# s#) of { StateAndMutableByteArray# s2# barr# ->
273 (_MutableByteArray ixs barr#, S# s2#)}
278 boundsOfArray :: Ix ix => _MutableArray s ix elt -> (ix, ix)
279 boundsOfByteArray :: Ix ix => _MutableByteArray s ix -> (ix, ix)
281 {-# SPECIALIZE boundsOfArray :: _MutableArray s Int elt -> IPr #-}
282 {-# SPECIALIZE boundsOfByteArray :: _MutableByteArray s Int -> IPr #-}
284 boundsOfArray (_MutableArray ixs _) = ixs
285 boundsOfByteArray (_MutableByteArray ixs _) = ixs
289 readArray :: Ix ix => _MutableArray s ix elt -> ix -> _ST s elt
291 readCharArray :: Ix ix => _MutableByteArray s ix -> ix -> _ST s Char
292 readIntArray :: Ix ix => _MutableByteArray s ix -> ix -> _ST s Int
293 readAddrArray :: Ix ix => _MutableByteArray s ix -> ix -> _ST s _Addr
294 readFloatArray :: Ix ix => _MutableByteArray s ix -> ix -> _ST s Float
295 readDoubleArray :: Ix ix => _MutableByteArray s ix -> ix -> _ST s Double
297 {-# SPECIALIZE readArray :: _MutableArray s Int elt -> Int -> _ST s elt,
298 _MutableArray s IPr elt -> IPr -> _ST s elt
300 {-# SPECIALIZE readCharArray :: _MutableByteArray s Int -> Int -> _ST s Char #-}
301 {-# SPECIALIZE readIntArray :: _MutableByteArray s Int -> Int -> _ST s Int #-}
302 {-# SPECIALIZE readAddrArray :: _MutableByteArray s Int -> Int -> _ST s _Addr #-}
303 --NO:{-# SPECIALIZE readFloatArray :: _MutableByteArray s Int -> Int -> _ST s Float #-}
304 {-# SPECIALIZE readDoubleArray :: _MutableByteArray s Int -> Int -> _ST s Double #-}
306 readArray (_MutableArray ixs arr#) n (S# s#)
307 = case (index ixs n) of { I# n# ->
308 case readArray# arr# n# s# of { StateAndPtr# s2# r ->
311 readCharArray (_MutableByteArray ixs barr#) n (S# s#)
312 = case (index ixs n) of { I# n# ->
313 case readCharArray# barr# n# s# of { StateAndChar# s2# r# ->
316 readIntArray (_MutableByteArray ixs barr#) n (S# s#)
317 = case (index ixs n) of { I# n# ->
318 case readIntArray# barr# n# s# of { StateAndInt# s2# r# ->
321 readAddrArray (_MutableByteArray ixs barr#) n (S# s#)
322 = case (index ixs n) of { I# n# ->
323 case readAddrArray# barr# n# s# of { StateAndAddr# s2# r# ->
326 readFloatArray (_MutableByteArray ixs barr#) n (S# s#)
327 = case (index ixs n) of { I# n# ->
328 case readFloatArray# barr# n# s# of { StateAndFloat# s2# r# ->
331 readDoubleArray (_MutableByteArray ixs barr#) n (S# s#)
332 = case (index ixs n) of { I# n# ->
333 -- trace ("readDoubleArray:"++(show (I# n#))) (
334 case readDoubleArray# barr# n# s# of { StateAndDouble# s2# r# ->
338 Indexing of ordinary @Arrays@ is standard Haskell and isn't defined here.
340 indexCharArray :: Ix ix => _ByteArray ix -> ix -> Char
341 indexIntArray :: Ix ix => _ByteArray ix -> ix -> Int
342 indexAddrArray :: Ix ix => _ByteArray ix -> ix -> _Addr
343 indexFloatArray :: Ix ix => _ByteArray ix -> ix -> Float
344 indexDoubleArray :: Ix ix => _ByteArray ix -> ix -> Double
346 {-# SPECIALIZE indexCharArray :: _ByteArray Int -> Int -> Char #-}
347 {-# SPECIALIZE indexIntArray :: _ByteArray Int -> Int -> Int #-}
348 {-# SPECIALIZE indexAddrArray :: _ByteArray Int -> Int -> _Addr #-}
349 --NO:{-# SPECIALIZE indexFloatArray :: _ByteArray Int -> Int -> Float #-}
350 {-# SPECIALIZE indexDoubleArray :: _ByteArray Int -> Int -> Double #-}
352 indexCharArray (_ByteArray ixs barr#) n
353 = case (index ixs n) of { I# n# ->
354 case indexCharArray# barr# n# of { r# ->
357 indexIntArray (_ByteArray ixs barr#) n
358 = case (index ixs n) of { I# n# ->
359 case indexIntArray# barr# n# of { r# ->
362 indexAddrArray (_ByteArray ixs barr#) n
363 = case (index ixs n) of { I# n# ->
364 case indexAddrArray# barr# n# of { r# ->
367 indexFloatArray (_ByteArray ixs barr#) n
368 = case (index ixs n) of { I# n# ->
369 case indexFloatArray# barr# n# of { r# ->
372 indexDoubleArray (_ByteArray ixs barr#) n
373 = case (index ixs n) of { I# n# ->
374 -- trace ("indexDoubleArray:"++(show (I# n#))) (
375 case indexDoubleArray# barr# n# of { r# ->
379 Indexing off @_Addrs@ is similar, and therefore given here.
381 indexCharOffAddr :: _Addr -> Int -> Char
382 indexIntOffAddr :: _Addr -> Int -> Int
383 indexAddrOffAddr :: _Addr -> Int -> _Addr
384 indexFloatOffAddr :: _Addr -> Int -> Float
385 indexDoubleOffAddr :: _Addr -> Int -> Double
387 indexCharOffAddr (A# addr#) n
388 = case n of { I# n# ->
389 case indexCharOffAddr# addr# n# of { r# ->
392 indexIntOffAddr (A# addr#) n
393 = case n of { I# n# ->
394 case indexIntOffAddr# addr# n# of { r# ->
397 indexAddrOffAddr (A# addr#) n
398 = case n of { I# n# ->
399 case indexAddrOffAddr# addr# n# of { r# ->
402 indexFloatOffAddr (A# addr#) n
403 = case n of { I# n# ->
404 case indexFloatOffAddr# addr# n# of { r# ->
407 indexDoubleOffAddr (A# addr#) n
408 = case n of { I# n# ->
409 case indexDoubleOffAddr# addr# n# of { r# ->
414 writeArray :: Ix ix => _MutableArray s ix elt -> ix -> elt -> _ST s ()
415 writeCharArray :: Ix ix => _MutableByteArray s ix -> ix -> Char -> _ST s ()
416 writeIntArray :: Ix ix => _MutableByteArray s ix -> ix -> Int -> _ST s ()
417 writeAddrArray :: Ix ix => _MutableByteArray s ix -> ix -> _Addr -> _ST s ()
418 writeFloatArray :: Ix ix => _MutableByteArray s ix -> ix -> Float -> _ST s ()
419 writeDoubleArray :: Ix ix => _MutableByteArray s ix -> ix -> Double -> _ST s ()
421 {-# SPECIALIZE writeArray :: _MutableArray s Int elt -> Int -> elt -> _ST s (),
422 _MutableArray s IPr elt -> IPr -> elt -> _ST s ()
424 {-# SPECIALIZE writeCharArray :: _MutableByteArray s Int -> Int -> Char -> _ST s () #-}
425 {-# SPECIALIZE writeIntArray :: _MutableByteArray s Int -> Int -> Int -> _ST s () #-}
426 {-# SPECIALIZE writeAddrArray :: _MutableByteArray s Int -> Int -> _Addr -> _ST s () #-}
427 --NO:{-# SPECIALIZE writeFloatArray :: _MutableByteArray s Int -> Int -> Float -> _ST s () #-}
428 {-# SPECIALIZE writeDoubleArray :: _MutableByteArray s Int -> Int -> Double -> _ST s () #-}
430 writeArray (_MutableArray ixs arr#) n ele (S# s#)
431 = case index ixs n of { I# n# ->
432 case writeArray# arr# n# ele s# of { s2# ->
435 writeCharArray (_MutableByteArray ixs barr#) n (C# ele) (S# s#)
436 = case (index ixs n) of { I# n# ->
437 case writeCharArray# barr# n# ele s# of { s2# ->
440 writeIntArray (_MutableByteArray ixs barr#) n (I# ele) (S# s#)
441 = case (index ixs n) of { I# n# ->
442 case writeIntArray# barr# n# ele s# of { s2# ->
445 writeAddrArray (_MutableByteArray ixs barr#) n (A# ele) (S# s#)
446 = case (index ixs n) of { I# n# ->
447 case writeAddrArray# barr# n# ele s# of { s2# ->
450 writeFloatArray (_MutableByteArray ixs barr#) n (F# ele) (S# s#)
451 = case (index ixs n) of { I# n# ->
452 case writeFloatArray# barr# n# ele s# of { s2# ->
455 writeDoubleArray (_MutableByteArray ixs barr#) n (D# ele) (S# s#)
456 = case (index ixs n) of { I# n# ->
457 -- trace ("writeDoubleArray:"++(show (I# n#))) (
458 case writeDoubleArray# barr# n# ele s# of { s2# ->
463 freezeArray :: Ix ix => _MutableArray s ix elt -> _ST s (Array ix elt)
464 freezeCharArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
465 freezeIntArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
466 freezeAddrArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
467 freezeFloatArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
468 freezeDoubleArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
470 {-# SPECIALISE freezeArray :: _MutableArray s Int elt -> _ST s (Array Int elt),
471 _MutableArray s IPr elt -> _ST s (Array IPr elt)
473 {-# SPECIALISE freezeCharArray :: _MutableByteArray s Int -> _ST s (_ByteArray Int) #-}
475 freezeArray (_MutableArray ixs@(ix_start, ix_end) arr#) (S# s#)
476 = let n# = case (if null (range ixs)
478 else (index ixs ix_end) + 1) of { I# x -> x }
480 case freeze arr# n# s# of { StateAndArray# s2# frozen# ->
481 (_Array ixs frozen#, S# s2#)}
483 freeze :: MutableArray# s ele -- the thing
484 -> Int# -- size of thing to be frozen
485 -> State# s -- the Universe and everything
486 -> StateAndArray# s ele
489 = case newArray# n# init s# of { StateAndMutableArray# s2# newarr1# ->
490 case copy 0# n# arr# newarr1# s2# of { StateAndMutableArray# s3# newarr2# ->
491 unsafeFreezeArray# newarr2# s3#
494 init = error "freezeArr: element not copied"
497 -> MutableArray# s ele -> MutableArray# s ele
499 -> StateAndMutableArray# s ele
501 copy cur# end# from# to# s#
503 = StateAndMutableArray# s# to#
505 = case readArray# from# cur# s# of { StateAndPtr# s1# ele ->
506 case writeArray# to# cur# ele s1# of { s2# ->
507 copy (cur# +# 1#) end# from# to# s2#
510 freezeCharArray (_MutableByteArray ixs@(ix_start, ix_end) arr#) (S# s#)
511 = let n# = case (if null (range ixs)
513 else ((index ixs ix_end) + 1)) of { I# x -> x }
515 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
516 (_ByteArray ixs frozen#, S# s2#) }
518 freeze :: MutableByteArray# s -- the thing
519 -> Int# -- size of thing to be frozen
520 -> State# s -- the Universe and everything
521 -> StateAndByteArray# s
524 = case (newCharArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
525 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
526 unsafeFreezeByteArray# newarr2# s3#
530 -> MutableByteArray# s -> MutableByteArray# s
532 -> StateAndMutableByteArray# s
534 copy cur# end# from# to# s#
536 = StateAndMutableByteArray# s# to#
538 = case (readCharArray# from# cur# s#) of { StateAndChar# s1# ele ->
539 case (writeCharArray# to# cur# ele s1#) of { s2# ->
540 copy (cur# +# 1#) end# from# to# s2#
543 freezeIntArray (_MutableByteArray ixs@(ix_start, ix_end) arr#) (S# s#)
544 = let n# = case (if null (range ixs)
546 else ((index ixs ix_end) + 1)) of { I# x -> x }
548 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
549 (_ByteArray ixs frozen#, S# s2#) }
551 freeze :: MutableByteArray# s -- the thing
552 -> Int# -- size of thing to be frozen
553 -> State# s -- the Universe and everything
554 -> StateAndByteArray# s
557 = case (newIntArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
558 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
559 unsafeFreezeByteArray# newarr2# s3#
563 -> MutableByteArray# s -> MutableByteArray# s
565 -> StateAndMutableByteArray# s
567 copy cur# end# from# to# s#
569 = StateAndMutableByteArray# s# to#
571 = case (readIntArray# from# cur# s#) of { StateAndInt# s1# ele ->
572 case (writeIntArray# to# cur# ele s1#) of { s2# ->
573 copy (cur# +# 1#) end# from# to# s2#
576 freezeAddrArray (_MutableByteArray ixs@(ix_start, ix_end) arr#) (S# s#)
577 = let n# = case (if null (range ixs)
579 else ((index ixs ix_end) + 1)) of { I# x -> x }
581 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
582 (_ByteArray ixs frozen#, S# s2#) }
584 freeze :: MutableByteArray# s -- the thing
585 -> Int# -- size of thing to be frozen
586 -> State# s -- the Universe and everything
587 -> StateAndByteArray# s
590 = case (newAddrArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
591 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
592 unsafeFreezeByteArray# newarr2# s3#
596 -> MutableByteArray# s -> MutableByteArray# s
598 -> StateAndMutableByteArray# s
600 copy cur# end# from# to# s#
602 = StateAndMutableByteArray# s# to#
604 = case (readAddrArray# from# cur# s#) of { StateAndAddr# s1# ele ->
605 case (writeAddrArray# to# cur# ele s1#) of { s2# ->
606 copy (cur# +# 1#) end# from# to# s2#
609 freezeFloatArray (_MutableByteArray ixs@(ix_start, ix_end) arr#) (S# s#)
610 = let n# = case (if null (range ixs)
612 else ((index ixs ix_end) + 1)) of { I# x -> x }
614 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
615 (_ByteArray ixs frozen#, S# s2#) }
617 freeze :: MutableByteArray# s -- the thing
618 -> Int# -- size of thing to be frozen
619 -> State# s -- the Universe and everything
620 -> StateAndByteArray# s
623 = case (newFloatArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
624 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
625 unsafeFreezeByteArray# newarr2# s3#
629 -> MutableByteArray# s -> MutableByteArray# s
631 -> StateAndMutableByteArray# s
633 copy cur# end# from# to# s#
635 = StateAndMutableByteArray# s# to#
637 = case (readFloatArray# from# cur# s#) of { StateAndFloat# s1# ele ->
638 case (writeFloatArray# to# cur# ele s1#) of { s2# ->
639 copy (cur# +# 1#) end# from# to# s2#
642 freezeDoubleArray (_MutableByteArray ixs@(ix_start, ix_end) arr#) (S# s#)
643 = let n# = case (if null (range ixs)
645 else ((index ixs ix_end) + 1)) of { I# x -> x }
647 case freeze arr# n# s# of { StateAndByteArray# s2# frozen# ->
648 (_ByteArray ixs frozen#, S# s2#) }
650 freeze :: MutableByteArray# s -- the thing
651 -> Int# -- size of thing to be frozen
652 -> State# s -- the Universe and everything
653 -> StateAndByteArray# s
656 = case (newDoubleArray# n# s#) of { StateAndMutableByteArray# s2# newarr1# ->
657 case copy 0# n# arr# newarr1# s2# of { StateAndMutableByteArray# s3# newarr2# ->
658 unsafeFreezeByteArray# newarr2# s3#
662 -> MutableByteArray# s -> MutableByteArray# s
664 -> StateAndMutableByteArray# s
666 copy cur# end# from# to# s#
668 = StateAndMutableByteArray# s# to#
670 = case (readDoubleArray# from# cur# s#) of { StateAndDouble# s1# ele ->
671 case (writeDoubleArray# to# cur# ele s1#) of { s2# ->
672 copy (cur# +# 1#) end# from# to# s2#
677 unsafeFreezeArray :: Ix ix => _MutableArray s ix elt -> _ST s (Array ix elt)
678 unsafeFreezeByteArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
680 {-# SPECIALIZE unsafeFreezeByteArray :: _MutableByteArray s Int -> _ST s (_ByteArray Int)
683 unsafeFreezeArray (_MutableArray ixs arr#) (S# s#)
684 = case unsafeFreezeArray# arr# s# of { StateAndArray# s2# frozen# ->
685 (_Array ixs frozen#, S# s2#) }
687 unsafeFreezeByteArray (_MutableByteArray ixs arr#) (S# s#)
688 = case unsafeFreezeByteArray# arr# s# of { StateAndByteArray# s2# frozen# ->
689 (_ByteArray ixs frozen#, S# s2#) }
693 sameMutableArray :: _MutableArray s ix elt -> _MutableArray s ix elt -> Bool
694 sameMutableByteArray :: _MutableByteArray s ix -> _MutableByteArray s ix -> Bool
696 sameMutableArray (_MutableArray _ arr1#) (_MutableArray _ arr2#)
697 = sameMutableArray# arr1# arr2#
699 sameMutableByteArray (_MutableByteArray _ arr1#) (_MutableByteArray _ arr2#)
700 = sameMutableByteArray# arr1# arr2#
703 %************************************************************************
705 \subsection[PreludeGlaST-variables]{Variables}
707 %************************************************************************
710 type MutableVar s a = _MutableArray s Int a
714 newVar :: a -> _ST s (MutableVar s a)
715 readVar :: MutableVar s a -> _ST s a
716 writeVar :: MutableVar s a -> a -> _ST s ()
717 sameVar :: MutableVar s a -> MutableVar s a -> Bool
719 {- MUCH GRATUITOUS INEFFICIENCY: WDP 95/09:
721 newVar init s = newArray (0,0) init s
722 readVar v s = readArray v 0 s
723 writeVar v val s = writeArray v 0 val s
724 sameVar v1 v2 = sameMutableArray v1 v2
728 = case (newArray# 1# init s#) of { StateAndMutableArray# s2# arr# ->
729 (_MutableArray vAR_IXS arr#, S# s2#) }
731 vAR_IXS = error "Shouldn't access `bounds' of a MutableVar\n"
733 readVar (_MutableArray _ var#) (S# s#)
734 = case readArray# var# 0# s# of { StateAndPtr# s2# r ->
737 writeVar (_MutableArray _ var#) val (S# s#)
738 = case writeArray# var# 0# val s# of { s2# ->
741 sameVar (_MutableArray _ var1#) (_MutableArray _ var2#)
742 = sameMutableArray# var1# var2#