diff --git a/Math/FFT.hs b/Math/FFT.hs
--- a/Math/FFT.hs
+++ b/Math/FFT.hs
@@ -168,4 +168,3 @@
 ) where
 
 import Math.FFT.Base
-import Data.Array.CArray
diff --git a/Math/FFT/Base.hsc b/Math/FFT/Base.hsc
--- a/Math/FFT/Base.hsc
+++ b/Math/FFT/Base.hsc
@@ -21,7 +21,7 @@
 import Foreign.ForeignPtr
 import Foreign.Ptr
 import Foreign.Storable
-import Foreign.Storable.Complex
+import Foreign.Storable.Complex ()
 import System.IO.Unsafe (unsafePerformIO)
 
 #include <fftw3.h>
@@ -49,6 +49,7 @@
 -- | This lock must be taken during /planning/ of any transform.  The FFTW
 -- library is not thread-safe in the planning phase.  Thankfully, the lock is
 -- not needed during the execute phase.
+lock :: MVar ()
 lock = unsafePerformIO $ newMVar ()
 {-# NOINLINE lock #-}
 
@@ -165,6 +166,7 @@
  , c_forward = FFTW_FORWARD
  , c_backward = FFTW_BACKWARD }
 
+unSign :: Sign -> FFTWSign
 unSign DFTForward = c_forward
 unSign DFTBackward = c_backward
 
@@ -206,8 +208,11 @@
 
 -- | Corresponds to the @fftw_iodim@ structure.  It completely describes the
 -- layout of each dimension, before and after the transform.
-data IODim = IODim { n :: Int, is :: Int, os :: Int }
-    deriving (Eq, Show)
+data IODim = IODim { nIODim :: Int  -- ^ Logical size of dimension
+                   , isIODim :: Int -- ^ Stride along dimension in input array
+                   , osIODim :: Int -- ^ Stride along dimension in output array
+                   }
+    deriving (Eq, Show, Data, Typeable)
 
 instance Storable IODim where
     sizeOf _ = #{size fftw_iodim}
@@ -279,7 +284,9 @@
 dftCRON :: (FFTWReal r, Ix i, Shapable i) => [Int] -> CArray i (Complex r) -> CArray i r
 dftCRON = dftCROG estimate
 
+fzr :: b -> [a] -> [(a,b)]
 fzr = flip zip . repeat
+drr :: (FFTWReal r, Ix i, Shapable i) => Kind -> [Int] -> CArray i r -> CArray i r
 drr = (dftRRN .) . fzr
 
 -- | Multi-dimensional real to real transform.  The result is not normalized.
@@ -380,6 +387,7 @@
 
 -- Check if a flag is set.
 infix 7 `has`
+has :: Flag -> Flag -> Bool
 a `has` b = a .&. b == b
 
 -- | Try to transform a CArray with only one memory allocation (for the result).
@@ -416,7 +424,7 @@
     withCArray a $ \ip ->
         withForeignPtr ofp $ \op ->
             withForeignPtr wfp $ \wp -> do
-                p <- withLock $ planner (unFlag $ f') wp op
+                p <- withLock $ planner (unFlag f') wp op
                 copyArray wp ip sz
                 execute p
     unsafeForeignPtrToCArray ofp lu
@@ -426,9 +434,9 @@
 -- | All the logic for determining shape of resulting array, and how to do the transform.
 dftShape :: (Ix i, Shapable i, IArray CArray e)
              => DFT -> [Int] -> CArray i e -> ((i,i),TSpec)
-dftShape dft tdims arr = assert valid (oBounds,tspec)
-    where shp = shape arr
-          rnk = rank arr
+dftShape t tdims a = assert valid (oBounds,tspec)
+    where shp = shape a
+          rnk = rank a
           strides = shapeToStride shp
           valid = not (null tdims) && 0 <= minimum tdims
                   && maximum tdims < rnk && nub tdims == tdims
@@ -438,13 +446,13 @@
                     filt s = map (s !!) tdims
                     filt' s = map (s !!) ([0 .. rnk - 1] \\ tdims)
           oShape = adjust f ldim shp -- Physical shape of the output array
-              where f = case dft of
+              where f = case t of
                             RC  -> (\n -> n `div` 2 + 1)
                             CR  -> (\n -> (n - 1) * 2)
                             CRO -> (\n -> (n - 1) * 2 + 1)
                             _   -> id
           lShape = adjust f ldim shp -- Logical shape of the output array
-              where f = case dft of
+              where f = case t of
                             CR  -> (\n -> (n - 1) * 2)
                             CRO -> (\n -> (n - 1) * 2 + 1)
                             _   -> id
@@ -465,25 +473,25 @@
 -- | Complex to Complex DFT, un-normalized.
 dftGU :: (FFTWReal r, Ix i, Shapable i) => Sign -> Flag -> [Int] -> CArray i (Complex r) -> CArray i (Complex r)
 dftGU s f tdims ain = transformCArray f ain bds go
-    where go f ip op = withTSpec tspec $ \r ds hr hds ->
-                         plan_guru_dft r ds hr hds ip op (unSign s) f
+    where go f' ip op = withTSpec tspec $ \r ds hr hds ->
+                        plan_guru_dft r ds hr hds ip op (unSign s) f'
           (bds,tspec) = dftShape CC tdims ain
 
 -- | Real to Complex DFT.
 dftRCG :: (FFTWReal r, Ix i, Shapable i) => Flag -> [Int] -> CArray i r -> CArray i (Complex r)
 dftRCG f tdims ain = transformCArray f ain bds go
-    where go f ip op = withTSpec tspec $ \r ds hr hds ->
-                         plan_guru_dft_r2c r ds hr hds ip op f
+    where go f' ip op = withTSpec tspec $ \r ds hr hds ->
+                        plan_guru_dft_r2c r ds hr hds ip op f'
           (bds,tspec) = dftShape RC tdims ain
 
 -- | Complex to Real DFT.  The first argument determines whether the last
 -- transformed dimension is logically odd or even.  'True' implies the dimension
 -- is odd.
 dftCRG_ :: (FFTWReal r, Ix i, Shapable i) => Bool -> Flag -> [Int] -> CArray i (Complex r) -> CArray i r
-dftCRG_ odd f tdims ain = tCArr f ain bds go
-    where go f ip op = withTSpec tspec $ \r ds hr hds ->
-                         plan_guru_dft_c2r r ds hr hds ip op f
-          (bds,tspec) = dftShape (if odd then CRO else CR) tdims ain
+dftCRG_ isOdd f tdims ain = tCArr f ain bds go
+    where go f' ip op = withTSpec tspec $ \r ds hr hds ->
+                        plan_guru_dft_c2r r ds hr hds ip op f'
+          (bds,tspec) = dftShape (if isOdd then CRO else CR) tdims ain
           tCArr = if length tdims == 1 && f `has` preserveInput
                   -- A multi-dimensional C->R transform destroys its input.
                   -- Also, a one-dimensional transform is faster if it can
@@ -502,9 +510,9 @@
 -- | Real to Real transforms.
 dftRRG :: (FFTWReal r, Ix i, Shapable i) => Flag -> [(Int,Kind)] -> CArray i r -> CArray i r
 dftRRG f tk ain = tCArr f ain bds go
-    where go f ip op = withTSpec tspec $ \r ds hr hds ->
-                         withArray (map unKind ks) $ \pk ->
-                             plan_guru_r2r r ds hr hds ip op pk f
+    where go f' ip op = withTSpec tspec $ \r ds hr hds ->
+                        withArray (map unKind ks) $ \pk ->
+                            plan_guru_r2r r ds hr hds ip op pk f'
           (bds,tspec) = dftShape RR tdims ain
           (tdims,ks) = unzip tk
           tCArr = if any (== HC2R) ks && not (f `has` preserveInput)
diff --git a/fft.cabal b/fft.cabal
--- a/fft.cabal
+++ b/fft.cabal
@@ -1,5 +1,5 @@
 name:                fft
-version:             0.1.1
+version:             0.1.2
 synopsis:            Bindings to the FFTW library.
 description:
                      Bindings to the FFTW library.
@@ -13,10 +13,24 @@
 license-file:        LICENSE
 author:              Jed Brown
 maintainer:          <jed@59A2.org>
-build-Depends:       base, array, carray, storable-complex
-extra-libraries:     fftw3
-extensions:	     ForeignFunctionInterface
-exposed-modules:     Math.FFT
-		     Math.FFT.Base
-ghc-options:         
 build-type:	     Simple
+cabal-version:       >= 1.2
+
+flag splitBase
+flag base4
+
+library
+  if flag(splitBase)
+    build-depends: base >= 3, array, carray, storable-complex
+  else
+    build-depends: base < 3, carray, storable-complex
+  if flag(base4)
+    build-depends: base >= 4 && < 5, syb >= 0.1
+  else
+    build-depends: base < 4
+
+  exposed-modules: Math.FFT
+                   Math.FFT.Base
+  extra-libraries: fftw3
+  extensions:      ForeignFunctionInterface
+  ghc-options:     -Wall
