{-# OPTIONS_GHC -fglasgow-exts #-} {- | Module : Data.StorableVector.ST.Strict License : BSD-style Maintainer : haskell@henning-thielemann.de Stability : experimental Portability : portable, requires ffi Tested with : GHC 6.4.1 Interface for access to a mutable StorableVector. -} module Data.StorableVector.ST.Lazy ( Vector, new, new_, read, write, modify, freeze, thaw, VST.length, runSTVector, mapST, mapSTLazy, ) where -- import qualified Data.StorableVector.Base as V import qualified Data.StorableVector as VS import qualified Data.StorableVector.Lazy as VL import qualified Data.StorableVector.ST.Strict as VST import Data.StorableVector.ST.Strict (Vector) import qualified Control.Monad.ST.Lazy as ST import Control.Monad.ST.Lazy (ST) import Foreign.Storable (Storable) -- import Prelude (Int, ($), (+), return, const, ) import Prelude hiding (read, length, ) {-# INLINE new #-} {-# INLINE new_ #-} {-# INLINE read #-} {-# INLINE write #-} {-# INLINE modify #-} {-# INLINE freeze #-} {-# INLINE thaw #-} {-# ONLINE length #-} {-# INLINE runSTVector #-} {-# INLINE mapST #-} {-# INLINE mapSTLazy #-} -- * access to mutable storable vector new :: (Storable e) => Int -> e -> ST s (Vector s e) new n x = ST.strictToLazyST (VST.new n x) new_ :: (Storable e) => Int -> ST s (Vector s e) new_ n = ST.strictToLazyST (VST.new_ n) {- | > Control.Monad.ST.runST (do arr <- new_ 10; Monad.zipWithM_ (write arr) [9,8..0] ['a'..]; read arr 3) -} read :: (Storable e) => Vector s e -> Int -> ST s e read xs n = ST.strictToLazyST (VST.read xs n) {- | > VS.unpack $ runSTVector (do arr <- new_ 10; Monad.zipWithM_ (write arr) [9,8..0] ['a'..]; return arr) -} write :: (Storable e) => Vector s e -> Int -> e -> ST s () write xs n x = ST.strictToLazyST (VST.write xs n x) modify :: (Storable e) => Vector s e -> Int -> (e -> e) -> ST s () modify xs n f = ST.strictToLazyST (VST.modify xs n f) freeze :: (Storable e) => Vector s e -> ST s (VS.Vector e) freeze xs = ST.strictToLazyST (VST.freeze xs) thaw :: (Storable e) => VS.Vector e -> ST s (Vector s e) thaw xs = ST.strictToLazyST (VST.thaw xs) runSTVector :: (Storable e) => (forall s. ST s (Vector s e)) -> VS.Vector e runSTVector m = VST.runSTVector (ST.lazyToStrictST m) -- * operations on immutable storable vector within ST monad {- | > :module + Data.STRef > VS.unpack $ Control.Monad.ST.runST (do ref <- newSTRef 'a'; mapST (\ _n -> do c <- readSTRef ref; modifySTRef ref succ; return c) (VS.pack [1,2,3,4::Data.Int.Int16])) -} mapST :: (Storable a, Storable b) => (a -> ST s b) -> VS.Vector a -> ST s (VS.Vector b) mapST f xs = ST.strictToLazyST (VST.mapST (ST.lazyToStrictST . f) xs) {- | > *Data.StorableVector.ST.Strict Data.STRef> VL.unpack $ Control.Monad.ST.runST (do ref <- newSTRef 'a'; mapSTLazy (\ _n -> do c <- readSTRef ref; modifySTRef ref succ; return c) (VL.pack VL.defaultChunkSize [1,2,3,4::Data.Int.Int16])) > "abcd" The following should not work on infinite streams, since we are in 'ST' with strict '>>='. But it works. Why? > *Data.StorableVector.ST.Strict Data.STRef.Lazy> VL.unpack $ Control.Monad.ST.Lazy.runST (do ref <- newSTRef 'a'; mapSTLazy (\ _n -> do c <- readSTRef ref; modifySTRef ref succ; return c) (VL.pack VL.defaultChunkSize [0::Data.Int.Int16 ..])) > "Interrupted. -} mapSTLazy :: (Storable a, Storable b) => (a -> ST s b) -> VL.Vector a -> ST s (VL.Vector b) mapSTLazy f (VL.SV xs) = fmap VL.SV $ mapM (mapST f) xs