primitive 0.1 → 0.2
raw patch · 4 files changed
+57/−15 lines, 4 files
Files
- Control/Monad/Primitive.hs +39/−1
- Data/Primitive/Array.hs +6/−6
- Data/Primitive/ByteArray.hs +10/−7
- primitive.cabal +2/−1
Control/Monad/Primitive.hs view
@@ -11,9 +11,14 @@ -- Primitive state-transformer monads -- -module Control.Monad.Primitive ( PrimMonad(..), primitive_ ) where+module Control.Monad.Primitive (+ PrimMonad(..), RealWorld, primitive_,+ primToPrim, primToIO, primToST,+ unsafePrimToPrim, unsafePrimToIO, unsafePrimToST+) where import GHC.Prim ( State#, RealWorld )+import GHC.Base ( unsafeCoerce# ) import GHC.IOBase ( IO(..) ) import GHC.ST ( ST(..) ) @@ -25,6 +30,10 @@ -- | Execute a primitive operation primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a ++ -- | Expose the internal structure of the monad+ internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)+ -- | Execute a primitive operation with no result primitive_ :: PrimMonad m => (State# (PrimState m) -> State# (PrimState m)) -> m ()@@ -34,8 +43,37 @@ instance PrimMonad IO where type PrimState IO = RealWorld primitive = IO+ internal (IO p) = p instance PrimMonad (ST s) where type PrimState (ST s) = s primitive = ST+ internal (ST p) = p++-- | Convert a 'PrimMonad' to another monad with the same state token.+primToPrim :: (PrimMonad m1, PrimMonad m2, PrimState m1 ~ PrimState m2)+ => m1 a -> m2 a+primToPrim m = primitive (internal m)++-- | Convert a 'PrimMonad' with a 'RealWorld' state token to 'IO'+primToIO :: (PrimMonad m, PrimState m ~ RealWorld) => m a -> IO a+primToIO = primToPrim++-- | Convert a 'PrimMonad' to 'ST'+primToST :: PrimMonad m => m a -> ST (PrimState m) a+primToST = primToPrim++-- | Convert a 'PrimMonad' to another monad with a possibly different state+-- token. This operation is highly unsafe!+unsafePrimToPrim :: (PrimMonad m1, PrimMonad m2) => m1 a -> m2 a+unsafePrimToPrim m = primitive (unsafeCoerce# (internal m))++-- | Convert any 'PrimMonad' to 'ST' with an arbitrary state token. This+-- operations is highly unsafe!+unsafePrimToST :: PrimMonad m => m a -> ST s a+unsafePrimToST = unsafePrimToPrim++-- | Convert any 'PrimMonad' to 'IO'. This operation is highly unsafe!+unsafePrimToIO :: PrimMonad m => m a -> IO a+unsafePrimToIO = unsafePrimToPrim
Data/Primitive/Array.hs view
@@ -27,23 +27,23 @@ data Array a = Array (Array# a) -- | Mutable boxed arrays associated with a primitive state token.-data MutableArray m a = MutableArray (MutableArray# (PrimState m) a)+data MutableArray s a = MutableArray (MutableArray# s a) -- | Create a new mutable array of the specified size and initialise all -- elements with the given value.-newArray :: PrimMonad m => Int -> a -> m (MutableArray m a)+newArray :: PrimMonad m => Int -> a -> m (MutableArray (PrimState m) a) {-# INLINE newArray #-} newArray (I# n#) x = primitive (\s# -> case newArray# n# x s# of (# s'#, arr# #) -> (# s'#, MutableArray arr# #)) -- | Read a value from the array at the given index.-readArray :: PrimMonad m => MutableArray m a -> Int -> m a+readArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> m a {-# INLINE readArray #-} readArray (MutableArray arr#) (I# i#) = primitive (readArray# arr# i#) -- | Write a value to the array at the given index.-writeArray :: PrimMonad m => MutableArray m a -> Int -> a -> m ()+writeArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> a -> m () {-# INLINE writeArray #-} writeArray (MutableArray arr#) (I# i#) x = primitive_ (writeArray# arr# i# x) @@ -82,7 +82,7 @@ -- | Convert a mutable array to an immutable one without copying. The -- array should not be modified after the conversion.-unsafeFreezeArray :: PrimMonad m => MutableArray m a -> m (Array a)+unsafeFreezeArray :: PrimMonad m => MutableArray (PrimState m) a -> m (Array a) {-# INLINE unsafeFreezeArray #-} unsafeFreezeArray (MutableArray arr#) = primitive (\s# -> case unsafeFreezeArray# arr# s# of@@ -90,7 +90,7 @@ -- | Convert an immutable array to an mutable one without copying. The -- immutable array should not be used after the conversion.-unsafeThawArray :: PrimMonad m => Array a -> m (MutableArray m a)+unsafeThawArray :: PrimMonad m => Array a -> m (MutableArray (PrimState m) a) {-# INLINE unsafeThawArray #-} unsafeThawArray (Array arr#) = primitive (\s# -> case unsafeThawArray# arr# s# of
Data/Primitive/ByteArray.hs view
@@ -31,10 +31,10 @@ data ByteArray = ByteArray ByteArray# -- | Mutable byte arrays associated with a primitive state token-data MutableByteArray m = MutableByteArray (MutableByteArray# (PrimState m))+data MutableByteArray s = MutableByteArray (MutableByteArray# s) -- | Create a new mutable byte array of the specified size.-newByteArray :: PrimMonad m => Int -> m (MutableByteArray m)+newByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m)) {-# INLINE newByteArray #-} newByteArray (I# n#) = primitive (\s# -> case newByteArray# n# s# of@@ -42,7 +42,7 @@ -- | Create a /pinned/ byte array of the specified size. The garbage collector -- is guaranteed not to move it.-newPinnedByteArray :: PrimMonad m => Int -> m (MutableByteArray m)+newPinnedByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m)) {-# INLINE newPinnedByteArray #-} newPinnedByteArray (I# n#) = primitive (\s# -> case newPinnedByteArray# n# s# of@@ -50,7 +50,8 @@ -- | Create a /pinned/ byte array of the specified size and with the give -- alignment. The garbage collector is guaranteed not to move it.-newAlignedPinnedByteArray :: PrimMonad m => Int -> Int -> m (MutableByteArray m)+newAlignedPinnedByteArray+ :: PrimMonad m => Int -> Int -> m (MutableByteArray (PrimState m)) {-# INLINE newAlignedPinnedByteArray #-} newAlignedPinnedByteArray (I# n#) (I# k#) = primitive (\s# -> case newAlignedPinnedByteArray# n# k# s# of@@ -71,7 +72,8 @@ -- | Convert a mutable byte array to an immutable one without copying. The -- array should not be modified after the conversion.-unsafeFreezeByteArray :: PrimMonad m => MutableByteArray m -> m ByteArray+unsafeFreezeByteArray+ :: PrimMonad m => MutableByteArray (PrimState m) -> m ByteArray {-# INLINE unsafeFreezeByteArray #-} unsafeFreezeByteArray (MutableByteArray arr#) = primitive (\s# -> case unsafeFreezeByteArray# arr# s# of@@ -95,7 +97,8 @@ -- | Read a primitive value from the byte array. The offset is given in -- elements of type @a@ rather than in bytes.-readByteArray :: (Prim a, PrimMonad m) => MutableByteArray m -> Int -> m a+readByteArray+ :: (Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> m a {-# INLINE readByteArray #-} readByteArray (MutableByteArray arr#) (I# i#) = primitive (readByteArray# arr# i#)@@ -103,7 +106,7 @@ -- | Write a primitive value to the byte array. The offset is given in -- elements of type @a@ rather than in bytes. writeByteArray- :: (Prim a, PrimMonad m) => MutableByteArray m -> Int -> a -> m ()+ :: (Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> a -> m () {-# INLINE writeByteArray #-} writeByteArray (MutableByteArray arr#) (I# i#) x = primitive_ (writeByteArray# arr# i# x)
primitive.cabal view
@@ -1,10 +1,11 @@ Name: primitive-Version: 0.1+Version: 0.2 License: BSD3 License-File: LICENSE Author: Roman Leshchinskiy <rl@cse.unsw.edu.au> Maintainer: Roman Leshchinskiy <rl@cse.unsw.edu.au> Copyright: (c) Roman Leshchinskiy 2009+Homepage: http://www.cse.unsw.edu.au/~rl/darcs/primitive Category: Data Synopsis: Wrappers for primitive operations Description: