diff --git a/Data/Array/CArray/Base.hs b/Data/Array/CArray/Base.hs
--- a/Data/Array/CArray/Base.hs
+++ b/Data/Array/CArray/Base.hs
@@ -1,6 +1,12 @@
-{-# OPTIONS_GHC -frewrite-rules #-}
 {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, MagicHash,
   FlexibleInstances, FlexibleContexts, UnboxedTuples, DeriveDataTypeable, CPP #-}
+#ifdef __GLASGOW_HASKELL__
+#if __GLASGOW_HASKELL__ < 610
+{-# OPTIONS_GHC -frewrite-rules #-}
+#else
+{-# OPTIONS_GHC -fenable-rewrite-rules #-}
+#endif
+#endif
 -----------------------------------------------------------------------------
 -- |
 -- Module      : Data.Array.CArray.Base
@@ -46,7 +52,7 @@
 import Foreign.ForeignPtr
 import Foreign.Ptr
 import Foreign.Marshal.Alloc
-import Foreign.Marshal.Array    (copyArray,peekArray,pokeArray)
+import Foreign.Marshal.Array    (copyArray)
 import Data.Word                (Word8,Word)
 
 import Data.Generics            (Data(..), Typeable(..))
@@ -66,14 +72,14 @@
 instance Storable e => MArray IOCArray e IO where
     getBounds (IOCArray l u _ _) = return (l,u)
 
-    getNumElements (IOCArray l u n _) = return n
+    getNumElements (IOCArray _ _ n _) = return n
 
-    newArray (l,u) init = do
-        fp <- mallocForeignPtrArrayAligned size
+    newArray (l,u) e0 = do
+        fp <- mallocForeignPtrArrayAligned n
         withForeignPtr fp $ \a ->
-            sequence_ [pokeElemOff a i init | i <- [0..size-1]]
-        return (IOCArray l u size fp)
-        where size = rangeSize (l,u)
+            sequence_ [pokeElemOff a i e0 | i <- [0 .. n - 1]]
+        return (IOCArray l u n fp)
+        where n = rangeSize (l,u)
 
     unsafeNewArray_ (l,u) = do
         let n = rangeSize (l,u)
@@ -127,9 +133,9 @@
 -- | /O(1)/ Turn a CArray into a ByteString.  Unsafe because it uses
 -- 'castForeignPtr' and thus is not platform independent.
 unsafeCArrayToByteString :: (Storable e) => CArray i e -> S.ByteString
-unsafeCArrayToByteString (CArray _ _ l fp) = go undefined l fp
-    where go :: (Storable e) => e -> Int -> ForeignPtr e -> S.ByteString
-          go dummy l fp = S.fromForeignPtr (castForeignPtr fp) 0 (l * sizeOf dummy)
+unsafeCArrayToByteString (CArray _ _ l fp) = go undefined fp
+    where go :: (Storable e) => e -> ForeignPtr e -> S.ByteString
+          go dummy fp' = S.fromForeignPtr (castForeignPtr fp') 0 (l * sizeOf dummy)
 
 -- | /O(1)/ Turn a ByteString into a CArray.  Unsafe because it uses
 -- 'castForeignPtr' and thus is not platform independent.  Returns 'Nothing' if
@@ -138,11 +144,10 @@
 -- CArray (as specified by the Storable instance).
 unsafeByteStringToCArray :: (Ix i, Storable e, IArray CArray e)
                             => (i,i) -> S.ByteString -> Maybe (CArray i e)
-unsafeByteStringToCArray (l,u) bs = go undefined (l,u) bs
-    where go :: (Ix i, Storable e, IArray CArray e)
-                => e -> (i,i) -> S.ByteString -> Maybe (CArray i e)
-          go dummy (l,u) bs | safe = Just (CArray l u n fp)
-                            | otherwise = Nothing
+unsafeByteStringToCArray lu bs = go undefined lu
+    where go :: (Ix i, Storable e, IArray CArray e) => e -> (i,i) -> Maybe (CArray i e)
+          go dummy (l,u) | safe = Just (CArray l u n fp)
+                         | otherwise = Nothing
               where n = rangeSize (l,u)
                     ((ForeignPtr addr contents), off, len) = S.toForeignPtr bs
                     p@(Ptr addr') = Ptr addr `plusPtr` off
@@ -150,7 +155,7 @@
                     safe = sizeOf dummy * n <= len && p == p `alignPtr` alignment dummy
 
 copy :: (Ix i, Storable e) => CArray i e -> IO (CArray i e)
-copy ain@(CArray l u n fp) =
+copy ain@(CArray l u n _) =
     createCArray (l,u) $ \op ->
         withCArray ain $ \ip ->
             copyArray op ip n
@@ -201,17 +206,17 @@
     {-# NOINLINE unsafeAccum #-}
     unsafeAccum f arr ies = unsafePerformIO $ unsafeAccumCArray f arr ies
     {-# NOINLINE unsafeAccumArray #-}
-    unsafeAccumArray f init lu ies = unsafePerformIO $ unsafeAccumArrayCArray f init lu ies
+    unsafeAccumArray f e0 lu ies = unsafePerformIO $ unsafeAccumArrayCArray f e0 lu ies
 
 
 -- | Hackish way to get the zero element for a Storable type.
 {-# NOINLINE zeroElem #-}
 zeroElem :: Storable a => a -> a
 zeroElem u = unsafePerformIO $ do
-    allocaBytes size $ \p -> do
-        sequence_ [pokeByteOff p off (0 :: Word8) | off <- [0 .. (size - 1)] ]
+    allocaBytes n $ \p -> do
+        sequence_ [pokeByteOff p off (0 :: Word8) | off <- [0 .. n - 1] ]
         peek (castPtr p)
-    where size = sizeOf u
+    where n = sizeOf u
 
 {-# INLINE unsafeArrayCArray #-}
 unsafeArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i)
@@ -245,8 +250,8 @@
 unsafeAccumArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i)
                           => (e -> e' -> e) -> e -> (i,i) -> [(Int, e')]
                                             -> IO (CArray i e)
-unsafeAccumArrayCArray f init lu ies = do
-    marr <- newArray lu init
+unsafeAccumArrayCArray f e0 lu ies = do
+    marr <- newArray lu e0
     sequence_ [do
         old <- unsafeRead marr i
         unsafeWrite marr i (f old new)
@@ -298,14 +303,14 @@
 -- | O(1) reshape an array.  The number of elements in the new shape must not
 -- exceed the number in the old shape.  The elements are in C-style ordering.
 reshape :: (Ix i, Ix j) => (j,j) -> CArray i e -> CArray j e
-reshape (l',u') (CArray l u n fp) | n' > n = error "reshape: new size too large"
-                                  |otherwise = CArray l' u' n' fp
+reshape (l',u') (CArray _ _ n fp) | n' > n = error "reshape: new size too large"
+                                  | otherwise = CArray l' u' n' fp
     where n' = rangeSize (l', u')
 
 -- | O(1) make a rank 1 array from an arbitrary shape.
 -- It has the property that 'reshape (0, size a - 1) a == flatten a'.
 flatten :: Ix i => CArray i e -> CArray Int e
-flatten (CArray l u n fp) = CArray 0 (n - 1) n fp
+flatten (CArray _ _ n fp) = CArray 0 (n - 1) n fp
 
 -- | Determine the rank of an array.
 rank :: (Shapable i, Ix i, IArray a e) => a i e -> Int
@@ -370,10 +375,10 @@
 sliceStrideWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e')
                     => (i',i') -> (i,i,i) -> (e -> e') -> a i e -> a' i' e'
 sliceStrideWithP lu (start,next,end) f arr
-    | all (inRange (bounds arr)) [start,next,end] = listArray lu elems
+    | all (inRange (bounds arr)) [start,next,end] = listArray lu es
     | otherwise = error "sliceStrideWith: out of bounds"
     where is = offsetShapeFromThenTo (shape arr) (index' start) (index' next) (index' end)
-          elems = map (f . (unsafeAt arr)) is
+          es = map (f . (unsafeAt arr)) is
           index' = indexes arr
 
 -- | Less polymorphic version.
@@ -395,10 +400,10 @@
 sliceWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e')
               => (i',i') -> (i,i) -> (e -> e') -> a i e -> a' i' e'
 sliceWithP lu (start,end) f arr
-    | all (inRange (bounds arr)) [start,end] = listArray lu elems
+    | all (inRange (bounds arr)) [start,end] = listArray lu es
     | otherwise = error "sliceWith: out of bounds"
     where is = offsetShapeFromTo (shape arr) (index' start) (index' end)
-          elems = map (f . (unsafeAt arr)) is
+          es = map (f . (unsafeAt arr)) is
           index' = indexes arr
 
 -- | Less polymorphic version.
@@ -432,21 +437,24 @@
 indexes :: (Ix i, Shapable i, IArray a e) => a i e -> i -> [Int]
 indexes a i = map pred $ (sShape . fst . bounds) a i
 
+offsetShapeFromThenTo :: [Int] -> [Int] -> [Int] -> [Int] -> [Int]
 offsetShapeFromThenTo s a b c = foldr (liftA2 (+)) [0] (ilists stride a b c)
-    where ilists = zipWith4 (\s a b c -> map (*s) $ enumFromThenTo a b c)
+    where ilists = zipWith4 (\s' a' b' c' -> map (*s') $ enumFromThenTo a' b' c')
           stride = shapeToStride s
 
+offsetShapeFromTo :: [Int] -> [Int] -> [Int] -> [Int]
 offsetShapeFromTo = offsetShapeFromTo' id
 
+offsetShapeFromTo' :: ([[Int]] -> [[Int]]) -> [Int] -> [Int] -> [Int] -> [Int]
 offsetShapeFromTo' f s a b = foldr (liftA2 (+)) [0] (f $ ilists stride a b)
-    where ilists = zipWith3 (\s a b -> map (*s) $ enumFromTo a b)
+    where ilists = zipWith3 (\s' a' b' -> map (*s') $ enumFromTo a' b')
           stride = shapeToStride s
 
 offsets :: (Ix a, Shapable a) => (a, a) -> a -> [Int]
 offsets lu i = reverse . osets (index lu i) . reverse . scanl1 (*) . uncurry sShape $ lu
     where osets 0 [] = []
-          osets i (b:bs) = r : osets d bs
-              where (d,r) = i `divMod` b
+          osets i' (b:bs) = r : osets d bs
+              where (d,r) = i' `divMod` b
           osets _ _ = error "osets"
 -----------------------------------------
 
@@ -457,7 +465,7 @@
 
 -- | 2-norm on the array taken as a vector (Frobenius norm for matrices)
 norm2 :: (Ix i, Floating e', Abs e e', IArray a e) => a i e -> e'
-norm2 a = sqrt $ foldl' (\z e -> z + abs_ e ^ 2) 0 (elems a)
+norm2 a = sqrt $ foldl' (\z e -> z + abs_ e ^ (2 :: Int)) 0 (elems a)
 
 -- | Sup norm on the array taken as a vector
 normSup :: (Ix i, Num e', Ord e', Abs e e', IArray a e) => a i e -> e'
@@ -512,23 +520,27 @@
     sRank _ = 1
     sShape a a' = [rangeSize (a,a')]
     sBounds [a] = (0,a-1)
+    sBounds _ = error "sBounds expected list length 1"
 
 instance Shapable (Int,Int) where
     sRank _ = 2
     sShape (a,b) (a',b') = [rangeSize (a,a'), rangeSize (b,b')]
     sBounds [a,b] = ((0,0),(a-1,b-1))
+    sBounds _ = error "sBounds expected list length 2"
 
 instance Shapable (Int,Int,Int) where
     sRank _ = 3
     sShape (a,b,c) (a',b',c') =
         [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c')]
     sBounds [a,b,c] = ((0,0,0),(a-1,b-1,c-1))
+    sBounds _ = error "sBounds expected list length 3"
 
 instance Shapable (Int,Int,Int,Int) where
     sRank _ = 4
     sShape (a,b,c,d) (a',b',c',d') =
         [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d')]
     sBounds [a,b,c,d] = ((0,0,0,0),(a-1,b-1,c-1,d-1))
+    sBounds _ = error "sBounds expected list length 4"
 
 instance Shapable (Int,Int,Int,Int,Int) where
     sRank _ = 5
@@ -536,6 +548,7 @@
         [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d')
         , rangeSize (e,e')]
     sBounds [a,b,c,d,e] = ((0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1))
+    sBounds _ = error "sBounds expected list length 5"
 
 instance Shapable (Int,Int,Int,Int,Int,Int) where
     sRank _ = 6
@@ -543,6 +556,7 @@
         [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d')
         , rangeSize (e,e'), rangeSize (f,f')]
     sBounds [a,b,c,d,e,f] = ((0,0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1,f-1))
+    sBounds _ = error "sBounds expected list length 6"
 
 instance Shapable (Int,Int,Int,Int,Int,Int,Int) where
     sRank _ = 7
@@ -550,6 +564,7 @@
         [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d')
         , rangeSize (e,e'), rangeSize (f,f'), rangeSize (g,g')]
     sBounds [a,b,c,d,e,f,g] = ((0,0,0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1,f-1,g-1))
+    sBounds _ = error "sBounds expected list length 7"
 
 instance Shapable (Int,Int,Int,Int,Int,Int,Int,Int) where
     sRank _ = 8
@@ -557,6 +572,7 @@
         [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d')
         , rangeSize (e,e'), rangeSize (f,f'), rangeSize (g,g'), rangeSize (h,h')]
     sBounds [a,b,c,d,e,f,g,h] = ((0,0,0,0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1,f-1,g-1,h-1))
+    sBounds _ = error "sBounds expected list length 8"
 
 instance Shapable (Int,Int,Int,Int,Int,Int,Int,Int,Int) where
     sRank _ = 9
@@ -566,6 +582,7 @@
         , rangeSize (i,i')]
     sBounds [a,b,c,d,e,f,g,h,i] = ((0,0,0,0,0,0,0,0,0)
                                   ,(a-1,b-1,c-1,d-1,e-1,f-1,g-1,h-1,i-1))
+    sBounds _ = error "sBounds expected list length 9"
 
 
 -- | Hack so that norms have a sensible type.
@@ -613,10 +630,10 @@
 
 -- | Allocate an array which is 16-byte aligned.  Essential for SIMD instructions.
 mallocForeignPtrArrayAligned :: Storable a => Int -> IO (ForeignPtr a)
-mallocForeignPtrArrayAligned n = doMalloc undefined n
+mallocForeignPtrArrayAligned n = doMalloc undefined
   where
-    doMalloc :: Storable b => b -> Int -> IO (ForeignPtr b)
-    doMalloc dummy size = mallocForeignPtrBytesAligned (size * sizeOf dummy)
+    doMalloc :: Storable b => b -> IO (ForeignPtr b)
+    doMalloc dummy = mallocForeignPtrBytesAligned (n * sizeOf dummy)
 
 -- | Allocate memory which is 16-byte aligned.  This is essential for SIMD
 -- instructions.  We know that mallocPlainForeignPtrBytes will give word-aligned
diff --git a/carray.cabal b/carray.cabal
--- a/carray.cabal
+++ b/carray.cabal
@@ -1,5 +1,5 @@
 name:                carray
-version:             0.1.2
+version:             0.1.3
 synopsis:            A C-compatible array library.
 description:
 		     A C-compatible array library.
@@ -18,7 +18,11 @@
 build-type:	     Simple
 
 flag splitBase
+  description: array was in base < 3
 flag bytestringInBase
+  description: bytestring was included in base for 2.0 and 2.1
+flag base4
+  description: syb was split from base >= 4 
 
 library
   if flag(bytestringInBase)
@@ -31,6 +35,12 @@
   else
     build-depends: base < 3, binary
 
+  if flag(base4)
+    build-depends: base >= 4, syb >= 0.1
+  else
+    build-depends: base < 4
+
   exposed-modules:   Data.Array.CArray
                      Data.Array.IOCArray
                      Data.Array.CArray.Base
+  ghc-options: -Wall
