diff --git a/primitive-checked.cabal b/primitive-checked.cabal
--- a/primitive-checked.cabal
+++ b/primitive-checked.cabal
@@ -1,5 +1,5 @@
 name: primitive-checked
-version: 0.6.3.0
+version: 0.6.4.0
 synopsis: primitive functions with bounds-checking
 homepage: https://github.com/andrewthad/primitive-checked#readme
 bug-reports: https://github.com/andrewthad/primitive-checked/issues
@@ -37,12 +37,14 @@
   hs-source-dirs:
       src
   build-depends:
-      base >=4.7 && <5
-    , primitive == 0.6.3.*
+      base >=4.9 && <5
+    , primitive == 0.6.4.*
   exposed-modules:
+    Data.Primitive
     Data.Primitive.Array
     Data.Primitive.SmallArray
     Data.Primitive.ByteArray
+    Data.Primitive.PrimArray
     Data.Primitive.UnliftedArray
   reexported-modules:
       Control.Monad.Primitive
diff --git a/src/Data/Primitive.hs b/src/Data/Primitive.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Primitive.hs
@@ -0,0 +1,15 @@
+module Data.Primitive (
+  module Data.Primitive.Types,
+  module Data.Primitive.Array,
+  module Data.Primitive.ByteArray,
+  module Data.Primitive.Addr,
+  module Data.Primitive.PrimArray,
+  module Data.Primitive.UnliftedArray
+) where
+
+import Data.Primitive.Types
+import Data.Primitive.Array
+import Data.Primitive.ByteArray
+import Data.Primitive.Addr
+import Data.Primitive.PrimArray
+import Data.Primitive.UnliftedArray
diff --git a/src/Data/Primitive/Array.hs b/src/Data/Primitive/Array.hs
--- a/src/Data/Primitive/Array.hs
+++ b/src/Data/Primitive/Array.hs
@@ -23,38 +23,40 @@
 
 import Control.Monad.Primitive (PrimMonad,PrimState)
 import Control.Exception (throw, ArrayException(..))
+import qualified Data.List as L
 import "primitive" Data.Primitive.Array (Array,MutableArray)
 import qualified "primitive" Data.Primitive.Array as A
+import GHC.Stack
 
-check :: String -> Bool -> a -> a
+check :: HasCallStack => String -> Bool -> a -> a
 check _      True  x = x
-check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.Array.Checked." ++ errMsg)
+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.Array.Checked." ++ errMsg ++ "\n" ++ prettyCallStack callStack)
 
-newArray :: PrimMonad m => Int -> a -> m (MutableArray (PrimState m) a)
+newArray :: (HasCallStack, PrimMonad m) => Int -> a -> m (MutableArray (PrimState m) a)
 newArray n x = check "newArray: negative size" (n>=0) (A.newArray n x)
 
-readArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> m a
+readArray :: (HasCallStack, PrimMonad m) => MutableArray (PrimState m) a -> Int -> m a
 readArray marr i = do
   let siz = A.sizeofMutableArray marr
   check "readArray: index of out bounds" (i>=0 && i<siz) (A.readArray marr i)
 
-writeArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> a -> m ()
+writeArray :: (HasCallStack, PrimMonad m) => MutableArray (PrimState m) a -> Int -> a -> m ()
 writeArray marr i x = do
   let siz = A.sizeofMutableArray marr
   check "writeArray: index of out bounds" (i>=0 && i<siz) (A.writeArray marr i x)
 
-indexArray :: Array a -> Int -> a
+indexArray :: HasCallStack => Array a -> Int -> a
 indexArray arr i = check "indexArray: index of out bounds"
   (i>=0 && i<A.sizeofArray arr)
   (A.indexArray arr i)
 
-indexArrayM :: Monad m => Array a -> Int -> m a
+indexArrayM :: HasCallStack => Monad m => Array a -> Int -> m a
 indexArrayM arr i = check "indexArrayM: index of out bounds"
     (i>=0 && i<A.sizeofArray arr)
     (A.indexArrayM arr i)
 
 freezeArray
-  :: PrimMonad m
+  :: (HasCallStack, PrimMonad m)
   => MutableArray (PrimState m) a -- ^ source
   -> Int                          -- ^ offset
   -> Int                          -- ^ length
@@ -66,7 +68,7 @@
     (A.freezeArray marr s l)
 
 thawArray
-  :: PrimMonad m
+  :: (HasCallStack, PrimMonad m)
   => Array a -- ^ source
   -> Int     -- ^ offset
   -> Int     -- ^ length
@@ -75,7 +77,7 @@
     (s>=0 && l>=0 && (s+l)<=A.sizeofArray arr)
     (A.thawArray arr s l)
 
-copyArray :: PrimMonad m
+copyArray :: (HasCallStack, PrimMonad m)
           => MutableArray (PrimState m) a    -- ^ destination array
           -> Int                             -- ^ offset into destination array
           -> Array a                         -- ^ source array
@@ -89,7 +91,7 @@
     (A.copyArray marr s1 arr s2 l)
 
 
-copyMutableArray :: PrimMonad m
+copyMutableArray :: (HasCallStack, PrimMonad m)
           => MutableArray (PrimState m) a    -- ^ destination array
           -> Int                             -- ^ offset into destination array
           -> MutableArray (PrimState m) a    -- ^ source array
@@ -99,12 +101,26 @@
 copyMutableArray marr1 s1 marr2 s2 l = do
   let siz1 = A.sizeofMutableArray marr1
   let siz2 = A.sizeofMutableArray marr2
-  check "copyMutableArray: index range of out bounds"
+  let explain = L.concat
+        [ "[dst size: "
+        , show siz1
+        , ", dst off: " 
+        , show s1
+        , ", src size: "
+        , show siz2
+        , ", src off: " 
+        , show s2
+        , ", copy size: "
+        , show l
+        , "]"
+        ]
+  check ("copyMutableArray: index range of out bounds " ++ explain)
     (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)
     (A.copyMutableArray marr1 s1 marr2 s2 l)
 
 
-cloneArray :: Array a -- ^ source array
+cloneArray :: HasCallStack
+           => Array a -- ^ source array
            -> Int     -- ^ offset into destination array
            -> Int     -- ^ number of elements to copy
            -> Array a
@@ -112,7 +128,7 @@
     (s>=0 && l>=0 && (s+l)<=A.sizeofArray arr)
     (A.cloneArray arr s l)
 
-cloneMutableArray :: PrimMonad m
+cloneMutableArray :: (HasCallStack, PrimMonad m)
         => MutableArray (PrimState m) a -- ^ source array
         -> Int                          -- ^ offset into destination array
         -> Int                          -- ^ number of elements to copy
diff --git a/src/Data/Primitive/ByteArray.hs b/src/Data/Primitive/ByteArray.hs
--- a/src/Data/Primitive/ByteArray.hs
+++ b/src/Data/Primitive/ByteArray.hs
@@ -43,42 +43,54 @@
 import Data.Word (Word8)
 import "primitive" Data.Primitive.ByteArray (ByteArray,MutableByteArray)
 import qualified "primitive" Data.Primitive.ByteArray as A
+import GHC.Stack
 
-check :: String -> Bool -> a -> a
+check :: HasCallStack => String -> Bool -> a -> a
 check _      True  x = x
-check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.SmallArray.Checked." ++ errMsg)
+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.ByteArray." ++ errMsg ++ "\n" ++ prettyCallStack callStack)
 
 elementSizeofByteArray :: forall a. Prim a => Proxy a -> ByteArray -> Int
 elementSizeofByteArray _ arr = div (A.sizeofByteArray arr) (sizeOf (undefined :: a))
 
+elementSizeofByteArrayPermissive :: forall a. Prim a => Proxy a -> ByteArray -> Int
+elementSizeofByteArrayPermissive _ arr =
+  div (A.sizeofByteArray arr) (sizeOf (undefined :: a)) + 
+  ( if rem (A.sizeofByteArray arr) (sizeOf (undefined :: a)) == 0
+      then 0
+      else 1
+  ) 
+
 elementSizeofMutableByteArray :: forall s a. Prim a => Proxy a -> MutableByteArray s -> Int
 elementSizeofMutableByteArray _ arr = div (A.sizeofMutableByteArray arr) (sizeOf (undefined :: a))
 
-newByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m))
+newByteArray :: (HasCallStack, PrimMonad m) => Int -> m (MutableByteArray (PrimState m))
 newByteArray n = check "newByteArray: negative size" (n>=0) (A.newByteArray n)
 
-newPinnedByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m))
+newPinnedByteArray :: (HasCallStack, PrimMonad m) => Int -> m (MutableByteArray (PrimState m))
 newPinnedByteArray n = check "newPinnedByteArray: negative size" (n>=0) (A.newPinnedByteArray n)
 
-newAlignedPinnedByteArray :: PrimMonad m => Int -> Int -> m (MutableByteArray (PrimState m))
+newAlignedPinnedByteArray :: (HasCallStack, PrimMonad m) => Int -> Int -> m (MutableByteArray (PrimState m))
 newAlignedPinnedByteArray n k = check "newAlignedPinnedByteArray: negative size" (n>=0) (A.newAlignedPinnedByteArray n k)
 
-readByteArray :: forall m a. (Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> m a
+readByteArray :: forall m a. (HasCallStack, Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> m a
 readByteArray marr i = do
   let siz = elementSizeofMutableByteArray (Proxy :: Proxy a) marr
   check "readByteArray: index of out bounds" (i>=0 && i<siz) (A.readByteArray marr i)
 
-writeByteArray :: forall m a. (Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> a -> m ()
+writeByteArray :: forall m a. (HasCallStack, Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> a -> m ()
 writeByteArray marr i x = do
   let siz = elementSizeofMutableByteArray (Proxy :: Proxy a) marr
   check "writeByteArray: index of out bounds" (i>=0 && i<siz) (A.writeByteArray marr i x)
 
-indexByteArray :: forall a. Prim a => ByteArray -> Int -> a
-indexByteArray arr i = check "indexSmallArray: index of out bounds"
-  (i>=0 && i< elementSizeofByteArray (Proxy :: Proxy a) arr)
+-- This one is a little special. We allow users to index past the
+-- end of the byte array as long as the content grabbed is within
+-- the last machine word of the byte array.
+indexByteArray :: forall a. (HasCallStack, Prim a) => ByteArray -> Int -> a
+indexByteArray arr i = check "indexByteArray: index of out bounds"
+  (i>=0 && i< elementSizeofByteArrayPermissive (Proxy :: Proxy a) arr)
   (A.indexByteArray arr i)
 
-copyByteArray :: forall m. PrimMonad m
+copyByteArray :: forall m. (HasCallStack, PrimMonad m)
   => MutableByteArray (PrimState m) -- ^ destination array
   -> Int -- ^ offset into destination array
   -> ByteArray -- ^ source array
@@ -92,7 +104,7 @@
     (A.copyByteArray marr s1 arr s2 l)
 
 
-copyMutableByteArray :: forall m. PrimMonad m
+copyMutableByteArray :: forall m. (HasCallStack, PrimMonad m)
   => MutableByteArray (PrimState m) -- ^ destination array
   -> Int -- ^ offset into destination array
   -> MutableByteArray (PrimState m) -- ^ source array
@@ -106,7 +118,7 @@
     (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)
     (A.copyMutableByteArray marr1 s1 marr2 s2 l)
 
-moveByteArray :: forall m. PrimMonad m
+moveByteArray :: forall m. (HasCallStack, PrimMonad m)
   => MutableByteArray (PrimState m) -- ^ destination array
   -> Int -- ^ offset into destination array
   -> MutableByteArray (PrimState m) -- ^ source array
@@ -120,7 +132,7 @@
     (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)
     (A.moveByteArray marr1 s1 marr2 s2 l)
 
-fillByteArray :: PrimMonad m
+fillByteArray :: (HasCallStack, PrimMonad m)
   => MutableByteArray (PrimState m) -- ^ array to fill
   -> Int -- ^ offset into array
   -> Int -- ^ number of bytes to fill
@@ -128,13 +140,12 @@
   -> m ()
 fillByteArray = setByteArray
 
-setByteArray :: forall m a. (Prim a, PrimMonad m)
+setByteArray :: forall m a. (HasCallStack, Prim a, PrimMonad m)
   => MutableByteArray (PrimState m) -- ^ array to fill
   -> Int -- ^ offset into array
   -> Int -- ^ number of values to fill
   -> a -- ^ value to fill with
   -> m ()
-{-# INLINE setByteArray #-}
 setByteArray dst doff sz x  = 
   check "copyMutableByteArray: index range of out bounds"
     (doff>=0 && (doff+sz)<=elementSizeofMutableByteArray (Proxy :: Proxy a) dst)
diff --git a/src/Data/Primitive/PrimArray.hs b/src/Data/Primitive/PrimArray.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Primitive/PrimArray.hs
@@ -0,0 +1,165 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE PackageImports #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+{-# OPTIONS_GHC -Wall #-}
+
+module Data.Primitive.PrimArray
+  ( -- * Types
+    PrimArray(..)
+  , MutablePrimArray(..)
+    -- * Allocation
+  , newPrimArray
+  , resizeMutablePrimArray
+#if __GLASGOW_HASKELL__ >= 710
+  , shrinkMutablePrimArray
+#endif
+    -- * Element Access
+  , readPrimArray
+  , writePrimArray
+  , indexPrimArray
+    -- * Freezing and Thawing
+  , A.unsafeFreezePrimArray
+  , A.unsafeThawPrimArray
+    -- * Block Operations
+  , copyPrimArray
+  , copyMutablePrimArray
+#if __GLASGOW_HASKELL__ >= 708
+  , A.copyPrimArrayToPtr -- this is wrong. fix this
+  , A.copyMutablePrimArrayToPtr -- this is wrong. fix this
+#endif
+  , setPrimArray
+    -- * Information
+  , A.sameMutablePrimArray
+  , A.getSizeofMutablePrimArray
+  , A.sizeofMutablePrimArray
+  , A.sizeofPrimArray
+    -- * Folding
+  , A.foldrPrimArray
+  , A.foldrPrimArray'
+  , A.foldlPrimArray
+  , A.foldlPrimArray'
+  , A.foldlPrimArrayM'
+    -- * Effectful Folding
+  , A.traversePrimArray_
+  , A.itraversePrimArray_
+    -- * Map/Create
+  , A.mapPrimArray
+  , A.imapPrimArray
+  , A.generatePrimArray
+  , A.replicatePrimArray
+  , A.filterPrimArray
+  , A.mapMaybePrimArray
+    -- * Effectful Map/Create
+    -- $effectfulMapCreate
+    -- ** Lazy Applicative
+  , A.traversePrimArray
+  , A.itraversePrimArray
+  , A.generatePrimArrayA
+  , A.replicatePrimArrayA
+  , A.filterPrimArrayA
+  , A.mapMaybePrimArrayA
+    -- ** Strict Primitive Monadic
+  , A.traversePrimArrayP
+  , A.itraversePrimArrayP
+  , A.generatePrimArrayP
+  , A.replicatePrimArrayP
+  , A.filterPrimArrayP
+  , A.mapMaybePrimArrayP
+  ) where
+
+import Control.Monad.Primitive (PrimMonad,PrimState)
+import Control.Exception (throw, ArrayException(..))
+import Data.Primitive.Types (Prim)
+import "primitive" Data.Primitive.PrimArray (PrimArray,MutablePrimArray)
+import qualified "primitive" Data.Primitive.PrimArray as A
+import GHC.Stack
+
+check :: HasCallStack => String -> Bool -> a -> a
+check _      True  x = x
+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.PrimArray." ++ errMsg ++ "\n" ++ prettyCallStack callStack)
+
+newPrimArray :: forall m a. (HasCallStack, PrimMonad m, Prim a) => Int -> m (MutablePrimArray (PrimState m) a)
+newPrimArray n = check "newPrimArray: negative size" (n>=0) (A.newPrimArray n)
+
+resizeMutablePrimArray :: forall m a. (HasCallStack, PrimMonad m, Prim a)
+  => MutablePrimArray (PrimState m) a
+  -> Int -- ^ new size
+  -> m (MutablePrimArray (PrimState m) a)
+resizeMutablePrimArray marr n = check "resizeMutablePrimArray: negative size" (n>=0) (A.resizeMutablePrimArray marr n)
+
+#if __GLASGOW_HASKELL__ >= 710
+shrinkMutablePrimArray :: forall m a. (HasCallStack, PrimMonad m, Prim a)
+  => MutablePrimArray (PrimState m) a
+  -> Int -- ^ new size
+  -> m ()
+shrinkMutablePrimArray marr n = do
+  old <- A.getSizeofMutablePrimArray marr
+  check "shrinkMutablePrimArray: illegal new size" (n>=0 && n <= old) (A.shrinkMutablePrimArray marr n)
+#endif
+
+readPrimArray :: (HasCallStack, Prim a, PrimMonad m) => MutablePrimArray (PrimState m) a -> Int -> m a
+readPrimArray marr i = do
+  siz <- A.getSizeofMutablePrimArray marr
+  check "readPrimArray: index of out bounds" (i>=0 && i<siz) (A.readPrimArray marr i)
+
+writePrimArray ::
+     (HasCallStack, Prim a, PrimMonad m)
+  => MutablePrimArray (PrimState m) a -- ^ array
+  -> Int -- ^ index
+  -> a -- ^ element
+  -> m ()
+writePrimArray marr i x = do
+  siz <- A.getSizeofMutablePrimArray marr
+  check "writePrimArray: index of out bounds" (i>=0 && i<siz) (A.writePrimArray marr i x)
+
+indexPrimArray :: forall a. Prim a => PrimArray a -> Int -> a
+indexPrimArray arr i = check "indexPrimArray: index of out bounds"
+  (i>=0 && i< A.sizeofPrimArray arr)
+  (A.indexPrimArray arr i)
+
+setPrimArray :: forall m a. (HasCallStack, Prim a, PrimMonad m)
+  => MutablePrimArray (PrimState m) a -- ^ array to fill
+  -> Int -- ^ offset into array
+  -> Int -- ^ number of values to fill
+  -> a -- ^ value to fill with
+  -> m ()
+setPrimArray dst doff sz x = do
+  arrSz <- A.getSizeofMutablePrimArray dst
+  check "copyMutablePrimArray: index range of out bounds"
+    (doff>=0 && (doff+sz)<=arrSz)
+    (A.setPrimArray dst doff sz x)
+
+copyMutablePrimArray :: forall m a. (HasCallStack, PrimMonad m, Prim a)
+  => MutablePrimArray (PrimState m) a -- ^ destination array
+  -> Int -- ^ offset into destination array
+  -> MutablePrimArray (PrimState m) a -- ^ source array
+  -> Int -- ^ offset into source array
+  -> Int -- ^ number of elements to copy
+  -> m ()
+copyMutablePrimArray marr1 s1 marr2 s2 l = do
+  siz1 <- A.getSizeofMutablePrimArray marr1
+  siz2 <- A.getSizeofMutablePrimArray marr2
+  check "copyMutablePrimArray: index range of out bounds"
+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)
+    (A.copyMutablePrimArray marr1 s1 marr2 s2 l)
+
+copyPrimArray :: forall m a.
+     (HasCallStack, PrimMonad m, Prim a)
+  => MutablePrimArray (PrimState m) a -- ^ destination array
+  -> Int -- ^ offset into destination array
+  -> PrimArray a -- ^ source array
+  -> Int -- ^ offset into source array
+  -> Int -- ^ number of elements to copy
+  -> m ()
+copyPrimArray marr s1 arr s2 l = do
+  siz <- A.getSizeofMutablePrimArray marr
+  check "copyPrimArray: index range of out bounds"
+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<= A.sizeofPrimArray arr && (s1+l)<=siz)
+    (A.copyPrimArray marr s1 arr s2 l)
+
diff --git a/src/Data/Primitive/SmallArray.hs b/src/Data/Primitive/SmallArray.hs
--- a/src/Data/Primitive/SmallArray.hs
+++ b/src/Data/Primitive/SmallArray.hs
@@ -24,36 +24,37 @@
 import Control.Exception (throw, ArrayException(..))
 import "primitive" Data.Primitive.SmallArray (SmallArray,SmallMutableArray)
 import qualified "primitive" Data.Primitive.SmallArray as A
+import GHC.Stack
 
-check :: String -> Bool -> a -> a
+check :: HasCallStack => String -> Bool -> a -> a
 check _      True  x = x
-check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.SmallArray.Checked." ++ errMsg)
+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.SmallArray.Checked." ++ errMsg ++ "\n" ++ prettyCallStack callStack)
 
-newSmallArray :: PrimMonad m => Int -> a -> m (SmallMutableArray (PrimState m) a)
+newSmallArray :: (HasCallStack, PrimMonad m) => Int -> a -> m (SmallMutableArray (PrimState m) a)
 newSmallArray n x = check "newSmallArray: negative size" (n>=0) (A.newSmallArray n x)
 
-readSmallArray :: PrimMonad m => SmallMutableArray (PrimState m) a -> Int -> m a
+readSmallArray :: (HasCallStack, PrimMonad m) => SmallMutableArray (PrimState m) a -> Int -> m a
 readSmallArray marr i = do
   let siz = A.sizeofSmallMutableArray marr
   check "readSmallArray: index of out bounds" (i>=0 && i<siz) (A.readSmallArray marr i)
 
-writeSmallArray :: PrimMonad m => SmallMutableArray (PrimState m) a -> Int -> a -> m ()
+writeSmallArray :: (HasCallStack, PrimMonad m) => SmallMutableArray (PrimState m) a -> Int -> a -> m ()
 writeSmallArray marr i x = do
   let siz = A.sizeofSmallMutableArray marr
   check "writeSmallArray: index of out bounds" (i>=0 && i<siz) (A.writeSmallArray marr i x)
 
-indexSmallArray :: SmallArray a -> Int -> a
+indexSmallArray :: HasCallStack => SmallArray a -> Int -> a
 indexSmallArray arr i = check "indexSmallArray: index of out bounds"
   (i>=0 && i<A.sizeofSmallArray arr)
   (A.indexSmallArray arr i)
 
-indexSmallArrayM :: Monad m => SmallArray a -> Int -> m a
+indexSmallArrayM :: (HasCallStack, Monad m) => SmallArray a -> Int -> m a
 indexSmallArrayM arr i = check "indexSmallArrayM: index of out bounds"
     (i>=0 && i<A.sizeofSmallArray arr)
     (A.indexSmallArrayM arr i)
 
 freezeSmallArray
-  :: PrimMonad m
+  :: (HasCallStack, PrimMonad m)
   => SmallMutableArray (PrimState m) a -- ^ source
   -> Int                          -- ^ offset
   -> Int                          -- ^ length
@@ -65,7 +66,7 @@
     (A.freezeSmallArray marr s l)
 
 thawSmallArray
-  :: PrimMonad m
+  :: (HasCallStack, PrimMonad m)
   => SmallArray a -- ^ source
   -> Int     -- ^ offset
   -> Int     -- ^ length
@@ -74,7 +75,7 @@
     (s>=0 && l>=0 && (s+l)<=A.sizeofSmallArray arr)
     (A.thawSmallArray arr s l)
 
-copySmallArray :: PrimMonad m
+copySmallArray :: (HasCallStack, PrimMonad m)
           => SmallMutableArray (PrimState m) a    -- ^ destination array
           -> Int                             -- ^ offset into destination array
           -> SmallArray a                         -- ^ source array
@@ -88,7 +89,7 @@
     (A.copySmallArray marr s1 arr s2 l)
 
 
-copySmallMutableArray :: PrimMonad m
+copySmallMutableArray :: (HasCallStack, PrimMonad m)
           => SmallMutableArray (PrimState m) a    -- ^ destination array
           -> Int                             -- ^ offset into destination array
           -> SmallMutableArray (PrimState m) a    -- ^ source array
@@ -103,7 +104,8 @@
     (A.copySmallMutableArray marr1 s1 marr2 s2 l)
 
 
-cloneSmallArray :: SmallArray a -- ^ source array
+cloneSmallArray :: HasCallStack
+           => SmallArray a -- ^ source array
            -> Int     -- ^ offset into destination array
            -> Int     -- ^ number of elements to copy
            -> SmallArray a
@@ -111,7 +113,7 @@
     (s>=0 && l>=0 && (s+l)<=A.sizeofSmallArray arr)
     (A.cloneSmallArray arr s l)
 
-cloneSmallMutableArray :: PrimMonad m
+cloneSmallMutableArray :: (HasCallStack, PrimMonad m)
         => SmallMutableArray (PrimState m) a -- ^ source array
         -> Int                          -- ^ offset into destination array
         -> Int                          -- ^ number of elements to copy
diff --git a/src/Data/Primitive/UnliftedArray.hs b/src/Data/Primitive/UnliftedArray.hs
--- a/src/Data/Primitive/UnliftedArray.hs
+++ b/src/Data/Primitive/UnliftedArray.hs
@@ -21,45 +21,48 @@
   , copyMutableUnliftedArray
   , cloneUnliftedArray
   , cloneMutableUnliftedArray
+  , A.mapUnliftedArray
+  , A.foldrUnliftedArray
   ) where
 
 import Control.Monad.Primitive (PrimMonad,PrimState)
 import Control.Exception (throw, ArrayException(..))
 import "primitive" Data.Primitive.UnliftedArray (UnliftedArray,MutableUnliftedArray,PrimUnlifted)
 import qualified "primitive" Data.Primitive.UnliftedArray as A
+import GHC.Stack
 
-check :: String -> Bool -> a -> a
+check :: HasCallStack => String -> Bool -> a -> a
 check _      True  x = x
-check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.UnliftedArray.Checked." ++ errMsg)
+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.UnliftedArray.Checked." ++ errMsg ++ "\n" ++ prettyCallStack callStack)
 
-newUnliftedArray :: (PrimMonad m, PrimUnlifted a) => Int -> a -> m (MutableUnliftedArray (PrimState m) a)
+newUnliftedArray :: (HasCallStack, PrimMonad m, PrimUnlifted a) => Int -> a -> m (MutableUnliftedArray (PrimState m) a)
 newUnliftedArray n x = check "newUnliftedArray: negative size" (n>=0) (A.newUnliftedArray n x)
 
-unsafeNewUnliftedArray :: PrimMonad m => Int -> m (MutableUnliftedArray (PrimState m) a)
+unsafeNewUnliftedArray :: (HasCallStack, PrimMonad m) => Int -> m (MutableUnliftedArray (PrimState m) a)
 unsafeNewUnliftedArray n = check "unsafeNewUnliftedArray: negative size" (n>=0) (A.unsafeNewUnliftedArray n)
 
-readUnliftedArray :: (PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> m a
+readUnliftedArray :: (HasCallStack, PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> m a
 readUnliftedArray marr i = do
   let siz = A.sizeofMutableUnliftedArray marr
   check "readUnliftedArray: index of out bounds" (i>=0 && i<siz) (A.readUnliftedArray marr i)
 
-writeUnliftedArray :: (PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> a -> m ()
+writeUnliftedArray :: (HasCallStack, PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> a -> m ()
 writeUnliftedArray marr i x = do
   let siz = A.sizeofMutableUnliftedArray marr
   check "writeUnliftedArray: index of out bounds" (i>=0 && i<siz) (A.writeUnliftedArray marr i x)
 
-indexUnliftedArray :: PrimUnlifted a => UnliftedArray a -> Int -> a
+indexUnliftedArray :: (HasCallStack, PrimUnlifted a) => UnliftedArray a -> Int -> a
 indexUnliftedArray arr i = check "indexUnliftedArray: index of out bounds"
   (i>=0 && i<A.sizeofUnliftedArray arr)
   (A.indexUnliftedArray arr i)
 
-indexUnliftedArrayM :: (Monad m, PrimUnlifted a) => UnliftedArray a -> Int -> m a
+indexUnliftedArrayM :: (HasCallStack, Monad m, PrimUnlifted a) => UnliftedArray a -> Int -> m a
 indexUnliftedArrayM arr i = check "indexUnliftedArrayM: index of out bounds"
     (i>=0 && i<A.sizeofUnliftedArray arr)
     (A.indexUnliftedArrayM arr i)
 
 freezeUnliftedArray
-  :: PrimMonad m
+  :: (HasCallStack, PrimMonad m)
   => MutableUnliftedArray (PrimState m) a -- ^ source
   -> Int -- ^ offset
   -> Int -- ^ length
@@ -71,7 +74,7 @@
     (A.freezeUnliftedArray marr s l)
 
 thawUnliftedArray
-  :: PrimMonad m
+  :: (HasCallStack, PrimMonad m)
   => UnliftedArray a -- ^ source
   -> Int -- ^ offset
   -> Int -- ^ length
@@ -80,7 +83,7 @@
     (s>=0 && l>=0 && (s+l)<=A.sizeofUnliftedArray arr)
     (A.thawUnliftedArray arr s l)
 
-copyUnliftedArray :: PrimMonad m
+copyUnliftedArray :: (HasCallStack, PrimMonad m)
   => MutableUnliftedArray (PrimState m) a -- ^ destination array
   -> Int -- ^ offset into destination array
   -> UnliftedArray a -- ^ source array
@@ -94,7 +97,7 @@
     (A.copyUnliftedArray marr s1 arr s2 l)
 
 
-copyMutableUnliftedArray :: PrimMonad m
+copyMutableUnliftedArray :: (HasCallStack, PrimMonad m)
   => MutableUnliftedArray (PrimState m) a    -- ^ destination array
   -> Int                             -- ^ offset into destination array
   -> MutableUnliftedArray (PrimState m) a    -- ^ source array
@@ -109,8 +112,8 @@
     (A.copyMutableUnliftedArray marr1 s1 marr2 s2 l)
 
 
-cloneUnliftedArray ::
-     UnliftedArray a -- ^ source array
+cloneUnliftedArray :: HasCallStack
+  => UnliftedArray a -- ^ source array
   -> Int -- ^ offset into destination array
   -> Int -- ^ number of elements to copy
   -> UnliftedArray a
@@ -118,7 +121,7 @@
     (s>=0 && l>=0 && (s+l)<=A.sizeofUnliftedArray arr)
     (A.cloneUnliftedArray arr s l)
 
-cloneMutableUnliftedArray :: PrimMonad m
+cloneMutableUnliftedArray :: (HasCallStack, PrimMonad m)
   => MutableUnliftedArray (PrimState m) a -- ^ source array
   -> Int -- ^ offset into destination array
   -> Int -- ^ number of elements to copy
