diff --git a/Data/Array/CArray.hs b/Data/Array/CArray.hs
--- a/Data/Array/CArray.hs
+++ b/Data/Array/CArray.hs
@@ -86,5 +86,6 @@
    module Data.Array.IArray
 ) where
 
+import Data.Ix.Shapable
 import Data.Array.IArray
 import Data.Array.CArray.Base
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
@@ -40,6 +40,7 @@
 
 import Control.Applicative
 import Control.Monad
+import Data.Ix.Shapable
 import Data.Array.Base
 import Data.Array.MArray
 import Data.Array.IArray
@@ -312,30 +313,7 @@
 flatten :: Ix i => CArray i e -> CArray Int e
 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
-rank = sRank . fst . bounds
-
 --
--- Useful for multi-dimensional arrays.  Not specific to CArray.
-
--- | Canonical representation of the shape.
--- The following properties hold:
---     'length . shape = rank'
---     'product . shape = size'
-shape :: (Shapable i, Ix i, IArray a e) => a i e -> [Int]
-shape = uncurry sShape . bounds
-
--- | How much the offset changes when you move one element in the given
--- direction.  Since arrays are in row-major order, 'last . shapeToStride = const 1'
-shapeToStride :: [Int] -> [Int]
-shapeToStride = scanr (*) 1 . tail
-
--- | Number of elements in the Array.
-size :: (Ix i, IArray a e) => a i e -> Int
-size = numElements
-
---
 -- None of the following are specific to CArray.  Some could have slightly
 -- faster versions specialized to CArray.  In general, slicing is expensive
 -- because the slice is not contiguous in memory, so must be copied.  There are
@@ -506,83 +484,6 @@
 liftArray3 :: (Ix i, IArray a e, IArray a e1, IArray a e2, IArray a e3)
               => (e -> e1 -> e2 -> e3) -> a i e -> a i e1 -> a i e2 -> a i e3
 liftArray3 = liftArray3P
-
-
--- | We need this type class to distinguish between different tuples of Ix.
--- There are Shapable instances for homogenous Int tuples, but may Haddock
--- doesn't see them.
-class Shapable i where
-    sRank :: i -> Int
-    sShape :: i -> i -> [Int]
-    sBounds :: [Int] -> (i,i)
-
-instance Shapable Int where
-    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
-    sShape (a,b,c,d,e) (a',b',c',d',e') =
-        [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
-    sShape (a,b,c,d,e,f) (a',b',c',d',e',f') =
-        [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
-    sShape (a,b,c,d,e,f,g) (a',b',c',d',e',f',g') =
-        [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
-    sShape (a,b,c,d,e,f,g,h) (a',b',c',d',e',f',g',h') =
-        [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
-    sShape (a,b,c,d,e,f,g,h,i) (a',b',c',d',e',f',g',h',i') =
-        [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d')
-        , rangeSize (e,e'), rangeSize (f,f'), rangeSize (g,g'), rangeSize (h,h')
-        , 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.
diff --git a/carray.cabal b/carray.cabal
--- a/carray.cabal
+++ b/carray.cabal
@@ -1,5 +1,5 @@
 name:                carray
-version:             0.1.3
+version:             0.1.4
 synopsis:            A C-compatible array library.
 description:
 		     A C-compatible array library.
@@ -25,6 +25,7 @@
   description: syb was split from base >= 4 
 
 library
+  build-depends:   ix-shapable
   if flag(bytestringInBase)
     build-depends: base >= 2.0 && < 2.2, binary
   else
