Initial version
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Tue, 13 Oct 2009 13:31:54 +0000 (13:31 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Tue, 13 Oct 2009 13:31:54 +0000 (13:31 +0000)
Control/Monad/Primitive.hs [new file with mode: 0644]
Data/Primitive/Addr.hs [new file with mode: 0644]
Data/Primitive/Array.hs [new file with mode: 0644]
Data/Primitive/ByteArray.hs [new file with mode: 0644]
Data/Primitive/MachDeps.hs [new file with mode: 0644]
Data/Primitive/Types.hs [new file with mode: 0644]
LICENSE [new file with mode: 0644]
Setup.hs [new file with mode: 0644]
array-primitives.cabal [new file with mode: 0644]

diff --git a/Control/Monad/Primitive.hs b/Control/Monad/Primitive.hs
new file mode 100644 (file)
index 0000000..ea2ef81
--- /dev/null
@@ -0,0 +1,41 @@
+{-# LANGUAGE MagicHash, UnboxedTuples, TypeFamilies #-}
+
+-- |
+-- Module      : Control.Monad.Primitive
+-- Copyright   : (c) Roman Leshchinskiy 2009
+-- License     : BSD-style
+--
+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Portability : non-portable
+-- 
+-- Primitive state-transformer monads
+--
+
+module Control.Monad.Primitive ( PrimMonad(..), primitive_ ) where
+
+import GHC.Prim   ( State#, RealWorld )
+import GHC.IOBase ( IO(..) )
+import GHC.ST     ( ST(..) )
+
+-- | Class of primitive state-transformer monads
+class Monad m => PrimMonad m where
+  -- | State token type
+  type PrimState m
+
+  -- | Execute a primitive operation
+  primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
+
+-- | Execute a primitive operation with no result
+primitive_ :: PrimMonad m
+              => (State# (PrimState m) -> State# (PrimState m)) -> m ()
+{-# INLINE primitive_ #-}
+primitive_ f = primitive (\s# -> (# f s#, () #))
+
+instance PrimMonad IO where
+  type PrimState IO = RealWorld
+  primitive = IO
+
+instance PrimMonad (ST s) where
+  type PrimState (ST s) = s
+  primitive = ST
+
diff --git a/Data/Primitive/Addr.hs b/Data/Primitive/Addr.hs
new file mode 100644 (file)
index 0000000..c622f0a
--- /dev/null
@@ -0,0 +1,51 @@
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+module Data.Primitive.Addr (
+  Addr(..),
+
+  nullAddr, plusAddr, minusAddr, remAddr,
+  indexOffAddr, readOffAddr, writeOffAddr
+) where
+
+import Control.Monad.Primitive
+import Data.Primitive.Types
+
+import GHC.Base ( Int(..) )
+import GHC.Prim
+
+instance Eq Addr where
+  Addr a# == Addr b# = eqAddr# a# b#
+  Addr a# /= Addr b# = neAddr# a# b#
+
+instance Ord Addr where
+  Addr a# > Addr b# = gtAddr# a# b#
+  Addr a# >= Addr b# = geAddr# a# b#
+  Addr a# < Addr b# = ltAddr# a# b#
+  Addr a# <= Addr b# = leAddr# a# b#
+
+nullAddr :: Addr
+nullAddr = Addr nullAddr#
+
+infixl 6 `plusAddr`, `minusAddr`
+infixl 7 `remAddr`
+
+plusAddr :: Addr -> Int -> Addr
+plusAddr (Addr a#) (I# i#) = Addr (plusAddr# a# i#)
+
+minusAddr :: Addr -> Addr -> Int
+minusAddr (Addr a#) (Addr b#) = I# (minusAddr# a# b#)
+
+remAddr :: Addr -> Int -> Int
+remAddr (Addr a#) (I# i#) = I# (remAddr# a# i#)
+
+indexOffAddr :: Prim a => Addr -> Int -> a
+{-# INLINE indexOffAddr #-}
+indexOffAddr (Addr addr#) (I# i#) = indexOffAddr# addr# i#
+
+readOffAddr :: (Prim a, PrimMonad m) => Addr -> Int -> m a
+{-# INLINE readOffAddr #-}
+readOffAddr (Addr addr#) (I# i#) = primitive (readOffAddr# addr# i#)
+
+writeOffAddr :: (Prim a, PrimMonad m) => Addr -> Int -> a -> m ()
+{-# INLINE writeOffAddr #-}
+writeOffAddr (Addr addr#) (I# i#) x = primitive_ (writeOffAddr# addr# i# x)
+
diff --git a/Data/Primitive/Array.hs b/Data/Primitive/Array.hs
new file mode 100644 (file)
index 0000000..f5aaf95
--- /dev/null
@@ -0,0 +1,44 @@
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+module Data.Primitive.Array (
+  Array(..), MutableArray(..),
+
+  newArray, readArray, writeArray, indexArray,
+  unsafeFreezeArray, unsafeThawArray, sameMutableArray
+) where
+
+import Control.Monad.Primitive
+
+import GHC.Base  ( Int(..) )
+import GHC.Prim
+
+data Array a = Array (Array# a)
+data MutableArray m a = MutableArray (MutableArray# (PrimState m) a)
+
+newArray :: PrimMonad m => Int -> a -> m (MutableArray m a)
+newArray (I# n#) x = primitive
+   (\s# -> case newArray# n# x s# of
+             (# s'#, arr# #) -> (# s'#, MutableArray arr# #))
+
+readArray :: PrimMonad m => MutableArray m a -> Int -> m a
+readArray (MutableArray arr#) (I# i#) = primitive (readArray# arr# i#)
+
+writeArray :: PrimMonad m => MutableArray m a -> Int -> a -> m ()
+writeArray (MutableArray arr#) (I# i#) x = primitive_ (writeArray# arr# i# x)
+
+indexArray :: Array a -> Int -> (a -> b) -> b
+indexArray (Array arr#) (I# i#) f = case indexArray# arr# i# of (# x #) -> f x
+
+unsafeFreezeArray :: PrimMonad m => MutableArray m a -> m (Array a)
+unsafeFreezeArray (MutableArray arr#)
+  = primitive (\s# -> case unsafeFreezeArray# arr# s# of
+                        (# s'#, arr'# #) -> (# s'#, Array arr'# #))
+
+unsafeThawArray :: PrimMonad m => Array a -> m (MutableArray m a)
+unsafeThawArray (Array arr#)
+  = primitive (\s# -> case unsafeThawArray# arr# s# of
+                        (# s'#, arr'# #) -> (# s'#, MutableArray arr'# #))
+
+sameMutableArray :: MutableArray m a -> MutableArray m a -> Bool
+sameMutableArray (MutableArray arr#) (MutableArray brr#)
+  = sameMutableArray# arr# brr#
+
diff --git a/Data/Primitive/ByteArray.hs b/Data/Primitive/ByteArray.hs
new file mode 100644 (file)
index 0000000..5678ecd
--- /dev/null
@@ -0,0 +1,66 @@
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+module Data.Primitive.ByteArray (
+  ByteArray(..), MutableByteArray(..),
+
+  newByteArray, newPinnedByteArray, newAlignedPinnedByteArray,
+  readByteArray, writeByteArray, indexByteArray,
+  unsafeFreezeByteArray,
+  sizeofByteArray, sizeofMutableByteArray, sameMutableByteArray,
+  byteArrayContents
+) where
+
+import Control.Monad.Primitive
+import Data.Primitive.Types
+
+import GHC.Base ( Int(..) )
+import GHC.Prim
+
+data ByteArray = ByteArray ByteArray#
+data MutableByteArray m = MutableByteArray (MutableByteArray# (PrimState m))
+
+newByteArray :: PrimMonad m => Int -> m (MutableByteArray m)
+newByteArray (I# n#)
+  = primitive (\s# -> case newByteArray# n# s# of
+                        (# s'#, arr# #) -> (# s'#, MutableByteArray arr# #))
+
+newPinnedByteArray :: PrimMonad m => Int -> m (MutableByteArray m)
+newPinnedByteArray (I# n#)
+  = primitive (\s# -> case newPinnedByteArray# n# s# of
+                        (# s'#, arr# #) -> (# s'#, MutableByteArray arr# #))
+
+newAlignedPinnedByteArray :: PrimMonad m => Int -> Int -> m (MutableByteArray m)
+newAlignedPinnedByteArray (I# n#) (I# k#)
+  = primitive (\s# -> case newAlignedPinnedByteArray# n# k# s# of
+                        (# s'#, arr# #) -> (# s'#, MutableByteArray arr# #))
+
+byteArrayContents :: ByteArray -> Addr
+byteArrayContents (ByteArray arr#) = Addr (byteArrayContents# arr#)
+
+sameMutableByteArray :: MutableByteArray m -> MutableByteArray m -> Bool
+sameMutableByteArray (MutableByteArray arr#) (MutableByteArray brr#)
+  = sameMutableByteArray# arr# brr#
+
+unsafeFreezeByteArray :: PrimMonad m => MutableByteArray m -> m ByteArray
+unsafeFreezeByteArray (MutableByteArray arr#)
+  = primitive (\s# -> case unsafeFreezeByteArray# arr# s# of
+                        (# s'#, arr'# #) -> (# s'#, ByteArray arr'# #))
+
+sizeofByteArray :: ByteArray -> Int
+sizeofByteArray (ByteArray arr#) = I# (sizeofByteArray# arr#)
+
+sizeofMutableByteArray :: MutableByteArray s -> Int
+sizeofMutableByteArray (MutableByteArray arr#) = I# (sizeofMutableByteArray# arr#)
+
+indexByteArray :: Prim a => ByteArray -> Int -> a
+indexByteArray (ByteArray arr#) (I# i#) = indexByteArray# arr# i#
+
+readByteArray :: (Prim a, PrimMonad m)
+              => MutableByteArray m -> Int -> m a
+readByteArray (MutableByteArray arr#) (I# i#)
+  = primitive (readByteArray# arr# i#)
+
+writeByteArray :: (Prim a, PrimMonad m)
+               => MutableByteArray m -> Int -> a -> m ()
+writeByteArray (MutableByteArray arr#) (I# i#) x
+  = primitive (\s# -> (# writeByteArray# arr# i# x s#, () #))
+
diff --git a/Data/Primitive/MachDeps.hs b/Data/Primitive/MachDeps.hs
new file mode 100644 (file)
index 0000000..5bb828e
--- /dev/null
@@ -0,0 +1,114 @@
+{-# LANGUAGE CPP #-}
+
+-- |
+-- Module      : Data.Primitive.MachDeps
+-- Copyright   : (c) Roman Leshchinskiy 2009
+-- License     : BSD-style
+--
+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Portability : non-portable
+-- 
+-- Machine-dependent constants
+--
+
+module Data.Primitive.MachDeps where
+
+#include "MachDeps.h"
+
+sIZEOF_CHAR,
+ aLIGNMENT_CHAR,
+
+ sIZEOF_INT,
+ aLIGNMENT_INT,
+
+ sIZEOF_WORD,
+ aLIGNMENT_WORD,
+
+ sIZEOF_DOUBLE,
+ aLIGNMENT_DOUBLE,
+
+ sIZEOF_FLOAT,
+ aLIGNMENT_FLOAT,
+
+ sIZEOF_PTR,
+ aLIGNMENT_PTR,
+
+ sIZEOF_FUNPTR,
+ aLIGNMENT_FUNPTR,
+
+ sIZEOF_STABLEPTR,
+ aLIGNMENT_STABLEPTR,
+
+ sIZEOF_INT8,
+ aLIGNMENT_INT8,
+
+ sIZEOF_WORD8,
+ aLIGNMENT_WORD8,
+
+ sIZEOF_INT16,
+ aLIGNMENT_INT16,
+
+ sIZEOF_WORD16,
+ aLIGNMENT_WORD16,
+
+ sIZEOF_INT32,
+ aLIGNMENT_INT32,
+
+ sIZEOF_WORD32,
+ aLIGNMENT_WORD32,
+
+ sIZEOF_INT64,
+ aLIGNMENT_INT64,
+
+ sIZEOF_WORD64,
+ aLIGNMENT_WORD64 :: Int
+
+
+sIZEOF_CHAR = SIZEOF_HSCHAR
+aLIGNMENT_CHAR = ALIGNMENT_HSCHAR
+
+sIZEOF_INT = SIZEOF_HSINT
+aLIGNMENT_INT = ALIGNMENT_HSINT
+
+sIZEOF_WORD = SIZEOF_HSWORD
+aLIGNMENT_WORD = ALIGNMENT_HSWORD
+
+sIZEOF_DOUBLE = SIZEOF_HSDOUBLE
+aLIGNMENT_DOUBLE = ALIGNMENT_HSDOUBLE
+
+sIZEOF_FLOAT = SIZEOF_HSFLOAT
+aLIGNMENT_FLOAT = ALIGNMENT_HSFLOAT
+
+sIZEOF_PTR = SIZEOF_HSPTR
+aLIGNMENT_PTR = ALIGNMENT_HSPTR
+
+sIZEOF_FUNPTR = SIZEOF_HSFUNPTR
+aLIGNMENT_FUNPTR = ALIGNMENT_HSFUNPTR
+
+sIZEOF_STABLEPTR = SIZEOF_HSSTABLEPTR
+aLIGNMENT_STABLEPTR = ALIGNMENT_HSSTABLEPTR
+
+sIZEOF_INT8 = SIZEOF_INT8
+aLIGNMENT_INT8 = ALIGNMENT_INT8
+
+sIZEOF_WORD8 = SIZEOF_WORD8
+aLIGNMENT_WORD8 = ALIGNMENT_WORD8
+
+sIZEOF_INT16 = SIZEOF_INT16
+aLIGNMENT_INT16 = ALIGNMENT_INT16
+
+sIZEOF_WORD16 = SIZEOF_WORD16
+aLIGNMENT_WORD16 = ALIGNMENT_WORD16
+
+sIZEOF_INT32 = SIZEOF_INT32
+aLIGNMENT_INT32 = ALIGNMENT_INT32
+
+sIZEOF_WORD32 = SIZEOF_WORD32
+aLIGNMENT_WORD32 = ALIGNMENT_WORD32
+
+sIZEOF_INT64 = SIZEOF_INT64
+aLIGNMENT_INT64 = ALIGNMENT_INT64
+
+sIZEOF_WORD64 = SIZEOF_WORD64
+aLIGNMENT_WORD64 = ALIGNMENT_WORD64
+
diff --git a/Data/Primitive/Types.hs b/Data/Primitive/Types.hs
new file mode 100644 (file)
index 0000000..29043e1
--- /dev/null
@@ -0,0 +1,116 @@
+{-# LANGUAGE UnboxedTuples, MagicHash, CPP #-}
+
+-- |
+-- Module      : Data.Primitive.Types
+-- Copyright   : (c) Roman Leshchinskiy 2009
+-- License     : BSD-style
+--
+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Portability : non-portable
+-- 
+-- Basic types and classes for primitive array operations
+--
+
+module Data.Primitive.Types (
+  Addr(..),
+  Prim(..), sizeOf, alignment
+) where
+
+import Control.Monad.Primitive
+import Data.Primitive.MachDeps
+
+import GHC.Base (
+    Int(..), Char(..),
+  )
+import GHC.Float (
+    Float(..), Double(..)
+  )
+import GHC.Word (
+    Word(..), Word8(..), Word16(..), Word32(..), Word64(..)
+  )
+import GHC.Int (
+    Int8(..), Int16(..), Int32(..), Int64(..)
+  )
+
+import GHC.Prim
+
+data Addr = Addr Addr#
+
+class Prim a where
+  sizeOf#    :: a -> Int#
+  alignment# :: a -> Int#
+
+  indexByteArray# :: ByteArray# -> Int# -> a
+  readByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
+  writeByteArray# :: MutableByteArray# s -> Int# -> a -> State# s -> State# s
+
+  indexOffAddr# :: Addr# -> Int# -> a
+  readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, a #)
+  writeOffAddr# :: Addr# -> Int# -> a -> State# s -> State# s
+
+sizeOf :: Prim a => a -> Int
+sizeOf x = I# (sizeOf# x)
+
+alignment :: Prim a => a -> Int
+alignment x = I# (alignment# x)
+
+#define derivePrim(ty, ctr, sz, align, idx_arr, rd_arr, wr_arr, idx_addr, rd_addr, wr_addr) \
+instance Prim ty where {                                        \
+  sizeOf# _ = unI# sz                                           \
+; alignment# _ = unI# align                                     \
+; indexByteArray# arr# i# = ctr (idx_arr arr# i#)               \
+; readByteArray#  arr# i# s# = case rd_arr arr# i# s# of        \
+                        { (# s1#, x# #) -> (# s1#, ctr x# #) }  \
+; writeByteArray# arr# i# (ctr x#) s# = wr_arr arr# i# x# s#    \
+                                                                \
+; indexOffAddr# addr# i# = ctr (idx_addr addr# i#)              \
+; readOffAddr#  addr# i# s# = case rd_addr addr# i# s# of       \
+                        { (# s1#, x# #) -> (# s1#, ctr x# #) }  \
+; writeOffAddr# addr# i# (ctr x#) s# = wr_addr addr# i# x# s#   }
+
+unI# :: Int -> Int#
+unI# (I# n#) = n#
+
+derivePrim(Word, W#, sIZEOF_WORD, aLIGNMENT_WORD,
+           indexWordArray#, readWordArray#, writeWordArray#,
+           indexWordOffAddr#, readWordOffAddr#, writeWordOffAddr#)
+derivePrim(Word8, W8#, sIZEOF_WORD8, aLIGNMENT_WORD8,
+           indexWord8Array#, readWord8Array#, writeWord8Array#,
+           indexWord8OffAddr#, readWord8OffAddr#, writeWord8OffAddr#)
+derivePrim(Word16, W16#, sIZEOF_WORD16, aLIGNMENT_WORD16,
+           indexWord16Array#, readWord16Array#, writeWord16Array#,
+           indexWord16OffAddr#, readWord16OffAddr#, writeWord16OffAddr#)
+derivePrim(Word32, W32#, sIZEOF_WORD32, aLIGNMENT_WORD32,
+           indexWord32Array#, readWord32Array#, writeWord32Array#,
+           indexWord32OffAddr#, readWord32OffAddr#, writeWord32OffAddr#)
+derivePrim(Word64, W64#, sIZEOF_WORD64, aLIGNMENT_WORD64,
+           indexWord64Array#, readWord64Array#, writeWord64Array#,
+           indexWord64OffAddr#, readWord64OffAddr#, writeWord64OffAddr#)
+derivePrim(Int, I#, sIZEOF_INT, aLIGNMENT_INT,
+           indexIntArray#, readIntArray#, writeIntArray#,
+           indexIntOffAddr#, readIntOffAddr#, writeIntOffAddr#)
+derivePrim(Int8, I8#, sIZEOF_INT8, aLIGNMENT_INT8,
+           indexInt8Array#, readInt8Array#, writeInt8Array#,
+           indexInt8OffAddr#, readInt8OffAddr#, writeInt8OffAddr#)
+derivePrim(Int16, I16#, sIZEOF_INT16, aLIGNMENT_INT16,
+           indexInt16Array#, readInt16Array#, writeInt16Array#,
+           indexInt16OffAddr#, readInt16OffAddr#, writeInt16OffAddr#)
+derivePrim(Int32, I32#, sIZEOF_INT32, aLIGNMENT_INT32,
+           indexInt32Array#, readInt32Array#, writeInt32Array#,
+           indexInt32OffAddr#, readInt32OffAddr#, writeInt32OffAddr#)
+derivePrim(Int64, I64#, sIZEOF_INT64, aLIGNMENT_INT64,
+           indexInt64Array#, readInt64Array#, writeInt64Array#,
+           indexInt64OffAddr#, readInt64OffAddr#, writeInt64OffAddr#)
+derivePrim(Float, F#, sIZEOF_FLOAT, aLIGNMENT_FLOAT,
+           indexFloatArray#, readFloatArray#, writeFloatArray#,
+           indexFloatOffAddr#, readFloatOffAddr#, writeFloatOffAddr#)
+derivePrim(Double, D#, sIZEOF_DOUBLE, aLIGNMENT_DOUBLE,
+           indexDoubleArray#, readDoubleArray#, writeDoubleArray#,
+           indexDoubleOffAddr#, readDoubleOffAddr#, writeDoubleOffAddr#)
+derivePrim(Char, C#, sIZEOF_CHAR, aLIGNMENT_CHAR,
+           indexWideCharArray#, readWideCharArray#, writeWideCharArray#,
+           indexWideCharOffAddr#, readWideCharOffAddr#, writeWideCharOffAddr#)
+derivePrim(Addr, Addr, sIZEOF_PTR, aLIGNMENT_PTR,
+           indexAddrArray#, readAddrArray#, writeAddrArray#,
+           indexAddrOffAddr#, readAddrOffAddr#, writeAddrOffAddr#)
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..fc213a6
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2008-2009, Roman Leshchinskiy
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+- Neither name of the University nor the names of its contributors may be
+used to endorse or promote products derived from this software without
+specific prior written permission. 
+
+THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
+GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644 (file)
index 0000000..200a2e5
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+main = defaultMain
+
diff --git a/array-primitives.cabal b/array-primitives.cabal
new file mode 100644 (file)
index 0000000..de6c73c
--- /dev/null
@@ -0,0 +1,30 @@
+Name:           array-primitives
+Version:        0.1
+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:       FIXME
+Category:       Data
+Synopsis:       Wrappers for primitive array operations
+Description:
+        .
+        This package provides wrappers for primitive array operations from
+        GHC.Prim.
+        .
+
+Cabal-Version:  >= 1.2
+Build-Type:     Simple
+
+Library
+  Exposed-Modules:
+        Control.Monad.Primitive
+        Data.Primitive.MachDeps
+        Data.Primitive.Types
+        Data.Primitive.Array
+        Data.Primitive.ByteArray
+        Data.Primitive.Addr
+
+  Build-Depends: base >= 2 && < 4, ghc-prim, ghc >= 6.10
+