diff --git a/Data/Array/Repa.hs b/Data/Array/Repa.hs
--- a/Data/Array/Repa.hs
+++ b/Data/Array/Repa.hs
@@ -1,6 +1,8 @@
 {-# OPTIONS -fno-warn-unused-imports #-}
 -- | Repa arrays are wrappers around a linear structure that holds the element
---   data. The representation tag determines what structure holds the data.
+--   data. 
+-- 
+--  The representation tag determines what structure holds the data.
 --
 --   Delayed Representations (functions that compute elements)
 --
@@ -65,7 +67,7 @@
 --     This is less of a problem for general Haskell code, and in a different
 --     context relying on strictness analysis is fine.
 --
---  5. Scheduling a parallel computation takes about 200us on an OSX machine. 
+--  5. Scheduling an 8-thread parallel computation can take 50us on a Linux machine. 
 --     You should switch to sequential evaluation functions like `computeS` and
 --     `foldS` for small arrays in inner loops, and at the bottom of a 
 --     divide-and-conquer algorithm. Consider using a `computeP` that evaluates
@@ -87,13 +89,24 @@
 --
 --  8. When you're sure your program works, switch to the unsafe versions
 --     of functions like `traverse`. These don't do bounds checks.
--- 
+--
+-- /Changes for Repa 3.2:/
+--
+--  1. Renamed some Repa 3.1 type classes to have more intuitive names: 
+--     `Repr` -> `Source`, `Fill` -> `Load`, `Fillable` -> `Target`, `Combine` -> `Structured`.
+--
+--  2. Also renamed `MArray` -> `MVec` to emphasise its linear structure.
+--
+--  3. Made `Array` and `MVec` associated types of `Source` and `Target` respectively.
+--
+--  4. Added the `S` (Smallness) and `I` (Interleave) hints.
+--
 module Data.Array.Repa
         ( -- * Abstract array representation
           module Data.Array.Repa.Shape
         , module Data.Array.Repa.Index
-        , Array(..)
-        , Repr(..), (!), toList
+        , Array (..)
+        , Source(..), (!), toList
         , deepSeqArrays
 
         -- * Computation
@@ -132,7 +145,7 @@
 	, map
 	, zipWith
 	, (+^), (-^), (*^), (/^)
-        , Combine(..)
+        , Structured(..)
 
 	-- from Data.Array.Repa.Operators.Traversal ------------------
 	-- ** Generic traversal
diff --git a/Data/Array/Repa/Base.hs b/Data/Array/Repa/Base.hs
--- a/Data/Array/Repa/Base.hs
+++ b/Data/Array/Repa/Base.hs
@@ -1,26 +1,24 @@
 
 module Data.Array.Repa.Base
-        ( Array
-        , Repr (..), (!), toList
+        ( Source (..), (!), toList
         , deepSeqArrays)
 where
 import Data.Array.Repa.Shape
 
--- | Arrays with a representation tag, shape, and element type.
---   Use one of the type tags like `D`, `U` and so on for @r@, 
---   one of `DIM1`, `DIM2` ... for @sh@.
-data family Array r sh e
 
-
--- Repr -----------------------------------------------------------------------
+-- Source -----------------------------------------------------------------------
 -- | Class of array representations that we can read elements from.
---
-class Repr r e where
+class Source r e where
+ -- Arrays with a representation tag, shape, and element type.
+ --   Use one of the type tags like `D`, `U` and so on for @r@, 
+ --   one of `DIM1`, `DIM2` ... for @sh@.
+ data Array r sh e
+
  -- | O(1). Take the extent (size) of an array.
- extent       :: Shape sh => Array r sh e -> sh
+ extent :: Shape sh => Array r sh e -> sh
 
  -- | O(1). Shape polymorphic indexing.
- index, unsafeIndex
+ index, unsafeIndex 
         :: Shape sh => Array r sh e -> sh -> e
 
  {-# INLINE index #-}
@@ -37,16 +35,17 @@
  unsafeLinearIndex      = linearIndex
 
  -- | Ensure an array's data structure is fully evaluated.
- deepSeqArray :: Shape sh => Array r sh e -> b -> b
+ deepSeqArray 
+        :: Shape sh =>Array r sh e -> b -> b
 
 
 -- | O(1). Alias for `index`
-(!) :: (Repr r e, Shape sh) => Array r sh e -> sh -> e
+(!) :: Shape sh => Source r e => Array r sh e -> sh -> e
 (!) = index
 
 
 -- | O(n). Convert an array to a list.
-toList  :: (Shape sh, Repr r e)
+toList  :: Shape sh => Source r e
         => Array r sh e -> [e]
 {-# INLINE toList #-}
 toList arr 
@@ -91,7 +90,7 @@
 --  If you're not sure, then just follow the example code above.
 --   
 deepSeqArrays 
-        :: (Shape sh, Repr r e)
+        :: Shape sh => Source r e
         => [Array r sh e] -> b -> b
 {-# INLINE deepSeqArrays #-}
 deepSeqArrays arrs x
diff --git a/Data/Array/Repa/Eval.hs b/Data/Array/Repa/Eval.hs
--- a/Data/Array/Repa/Eval.hs
+++ b/Data/Array/Repa/Eval.hs
@@ -6,9 +6,9 @@
           Elt       (..)
 
         -- * Parallel array filling
-        , Fillable  (..)
-        , Fill      (..)
-        , FillRange (..)
+        , Target    (..)
+        , Load      (..)
+        , LoadRange (..)
         , fromList
         
         -- * Converting between representations
@@ -37,7 +37,8 @@
         , selectChunkedP)
 where
 import Data.Array.Repa.Eval.Elt
-import Data.Array.Repa.Eval.Fill
+import Data.Array.Repa.Eval.Target
+import Data.Array.Repa.Eval.Load
 import Data.Array.Repa.Eval.Chunked
 import Data.Array.Repa.Eval.Interleaved
 import Data.Array.Repa.Eval.Cursored
@@ -60,7 +61,8 @@
 --     then use `delay` instead.
 --
 computeP 
-        :: (Shape sh, Fill r1 r2 sh e, Repr r2 e, Monad m)
+        :: ( Load r1 sh e
+           , Target r2 e, Source r2 e, Monad m)
         => Array r1 sh e -> m (Array r2 sh e)
 computeP arr = now $ suspendedComputeP arr
 {-# INLINE [4] computeP #-}
@@ -68,14 +70,14 @@
 
 -- | Sequential computation of array elements.
 computeS 
-        :: Fill r1 r2 sh e
+        :: (Load r1 sh e, Target r2 e)
         => Array r1 sh e -> Array r2 sh e
 computeS arr1
  = arr1 `deepSeqArray` 
    unsafePerformIO
- $ do   marr2    <- newMArr (size $ extent arr1) 
-        fillS arr1 marr2
-        unsafeFreezeMArr (extent arr1) marr2
+ $ do   mvec2   <- newMVec (size $ extent arr1) 
+        loadS arr1 mvec2
+        unsafeFreezeMVec (extent arr1) mvec2
 {-# INLINE [4] computeS #-}
 
 
@@ -91,14 +93,14 @@
 --   that each array is fully evaluated before continuing.
 --
 suspendedComputeP 
-        :: Fill r1 r2 sh e
+        :: (Load r1 sh e, Target r2 e)
         => Array r1 sh e -> Array r2 sh e
 suspendedComputeP arr1
  = arr1 `deepSeqArray` 
    unsafePerformIO
- $ do   marr2    <- newMArr (size $ extent arr1) 
-        fillP arr1 marr2
-        unsafeFreezeMArr (extent arr1) marr2
+ $ do   mvec2    <- newMVec (size $ extent arr1) 
+        loadP arr1 mvec2
+        unsafeFreezeMVec (extent arr1) mvec2
 {-# INLINE [4] suspendedComputeP #-}
 
 
@@ -108,14 +110,17 @@
 -- 
 --   * You can use it to copy manifest arrays between representations.
 --
-copyP  :: (Shape sh, Fill D r2 sh e, Repr r1 e, Repr r2 e, Monad m)
+copyP  :: ( Source r1 e, Source r2 e
+          , Load D sh e, Target r2 e
+          , Monad m)
         => Array r1 sh e -> m (Array r2 sh e)
 copyP arr = now $ suspendedCopyP arr
 {-# INLINE [4] copyP #-}
 
 
 -- | Sequential copying of arrays.
-copyS   :: (Repr r1 e, Fill D r2 sh e)
+copyS   :: ( Source r1 e
+           , Load D sh e, Target r2 e)
         => Array r1 sh e -> Array r2 sh e
 copyS arr1  = computeS $ delay arr1
 {-# INLINE [4] copyS #-}
@@ -123,7 +128,8 @@
 
 -- | Suspended parallel copy of array elements.
 suspendedCopyP   
-        :: (Repr r1 e, Fill D r2 sh e)
+        :: ( Source r1 e
+           , Load D sh e, Target r2 e)
         => Array r1 sh e -> Array r2 sh e
 suspendedCopyP arr1  = suspendedComputeP $ delay arr1
 {-# INLINE [4] suspendedCopyP #-}
@@ -140,9 +146,11 @@
 --     ...
 -- @
 --
-now     :: (Shape sh, Repr r e, Monad m)
+now     :: (Shape sh, Source r e, Monad m)
         => Array r sh e -> m (Array r sh e)
 now arr
  = do   arr `deepSeqArray` return ()
         return arr
 {-# INLINE [4] now #-}
+
+
diff --git a/Data/Array/Repa/Eval/Fill.hs b/Data/Array/Repa/Eval/Fill.hs
deleted file mode 100644
--- a/Data/Array/Repa/Eval/Fill.hs
+++ /dev/null
@@ -1,78 +0,0 @@
-
-module Data.Array.Repa.Eval.Fill
-        ( Fillable  (..), fromList
-        , Fill      (..)
-        , FillRange (..))
-where
-import Data.Array.Repa.Base
-import Data.Array.Repa.Shape
-import Control.Monad
-import System.IO.Unsafe
-
--- Fillable -------------------------------------------------------------------
--- | Class of manifest array representations that can be filled in parallel 
---   and then frozen into immutable Repa arrays.
-class Fillable r e where
-
- -- | Mutable version of the representation.
- data MArr r e
-
- -- | Allocate a new mutable array of the given size.
- newMArr          :: Int -> IO (MArr r e)
-
- -- | Write an element into the mutable array.
- unsafeWriteMArr  :: MArr r e -> Int -> e -> IO ()
-
- -- | Freeze the mutable array into an immutable Repa array.
- unsafeFreezeMArr :: sh  -> MArr r e -> IO (Array r sh e)
-
- -- | Ensure the strucure of a mutable array is fully evaluated.
- deepSeqMArr      :: MArr r e -> a -> a
-
- -- | Ensure the array is still live at this point.
- --   Needed when the mutable array is a ForeignPtr with a finalizer.
- touchMArr        :: MArr r e -> IO ()
-
-
--- | O(n). Construct a manifest array from a list.
-fromList
-        :: (Shape sh, Fillable r e)
-        => sh -> [e] -> Array r sh e
-fromList sh xx
- = unsafePerformIO
- $ do   let len = length xx
-        if len /= size sh
-         then error "Data.Array.Repa.Eval.Fill.fromList: provide array shape does not match list length"
-         else do
-                marr    <- newMArr len
-                zipWithM_ (unsafeWriteMArr marr) [0..] xx
-                unsafeFreezeMArr sh marr
-
-
--- Fill -----------------------------------------------------------------------
--- | Compute all elements defined by an array and write them to a fillable
---   representation.
---  
---   Note that instances require that the source array to have a delayed
---   representation such as `D` or `C`. If you want to use a pre-existing
---   manifest array as the source then `delay` it first.
-class (Shape sh, Repr r1 e, Fillable r2 e) => Fill r1 r2 sh e where
- -- | Fill an entire array sequentially.
- fillS          :: Array r1 sh e -> MArr r2 e -> IO ()
-
- -- | Fill an entire array in parallel.
- fillP          :: Array r1 sh e -> MArr r2 e -> IO ()
-
-
--- FillRange ------------------------------------------------------------------
--- | Compute a range of elements defined by an array and write them to a fillable
---   representation.
-class (Shape sh, Repr r1 e, Fillable r2 e) => FillRange r1 r2 sh e where
- -- | Fill a range of an array sequentially.
- fillRangeS     :: Array r1 sh e -> MArr r2 e -> sh -> sh -> IO ()
-
- -- | Fill a range of an array in parallel.
- fillRangeP     :: Array r1 sh e -> MArr r2 e -> sh -> sh -> IO ()
-
-
-                        
diff --git a/Data/Array/Repa/Eval/Load.hs b/Data/Array/Repa/Eval/Load.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/Repa/Eval/Load.hs
@@ -0,0 +1,36 @@
+
+module Data.Array.Repa.Eval.Load
+        ( Load      (..)
+        , LoadRange (..))
+where
+import Data.Array.Repa.Eval.Target
+import Data.Array.Repa.Shape
+import Data.Array.Repa.Base
+
+-- Load -----------------------------------------------------------------------
+-- | Compute all elements defined by an array and write them to a manifest
+--   target representation.
+--  
+--   Note that instances require that the source array to have a delayed
+--   representation such as `D` or `C`. If you want to use a pre-existing
+--   manifest array as the source then `delay` it first.
+class (Source r1 e, Shape sh) => Load r1 sh e where
+ -- | Fill an entire array sequentially.
+ loadS          :: Target r2 e => Array r1 sh e -> MVec r2 e -> IO ()
+
+ -- | Fill an entire array in parallel.
+ loadP          :: Target r2 e => Array r1 sh e -> MVec r2 e -> IO ()
+
+
+-- FillRange ------------------------------------------------------------------
+-- | Compute a range of elements defined by an array and write them to a fillable
+--   representation.
+class (Source r1 e, Shape sh) => LoadRange r1 sh e where
+ -- | Fill a range of an array sequentially.
+ loadRangeS     :: Target r2 e => Array r1 sh e -> MVec r2 e -> sh -> sh -> IO ()
+
+ -- | Fill a range of an array in parallel.
+ loadRangeP     :: Target r2 e => Array r1 sh e -> MVec r2 e -> sh -> sh -> IO ()
+
+
+                        
diff --git a/Data/Array/Repa/Eval/Target.hs b/Data/Array/Repa/Eval/Target.hs
new file mode 100644
--- /dev/null
+++ b/Data/Array/Repa/Eval/Target.hs
@@ -0,0 +1,49 @@
+
+module Data.Array.Repa.Eval.Target
+        ( Target    (..)
+        , fromList)
+where
+import Data.Array.Repa.Base
+import Data.Array.Repa.Shape
+import Control.Monad
+import System.IO.Unsafe
+
+
+-- Target ---------------------------------------------------------------------
+-- | Class of manifest array representations that can be constructed in parallel.
+class Target r e where
+
+ -- | Mutable version of the representation.
+ data MVec r e
+
+ -- | Allocate a new mutable array of the given size.
+ newMVec          :: Int -> IO (MVec r e)
+
+ -- | Write an element into the mutable array.
+ unsafeWriteMVec  :: MVec r e -> Int -> e -> IO ()
+
+ -- | Freeze the mutable array into an immutable Repa array.
+ unsafeFreezeMVec :: sh  -> MVec r e -> IO (Array r sh e)
+
+ -- | Ensure the strucure of a mutable array is fully evaluated.
+ deepSeqMVec      :: MVec r e -> a -> a
+
+ -- | Ensure the array is still live at this point.
+ --   Needed when the mutable array is a ForeignPtr with a finalizer.
+ touchMVec        :: MVec r e -> IO ()
+
+
+-- | O(n). Construct a manifest array from a list.
+fromList :: (Shape sh, Target r e)
+         => sh -> [e] -> Array r sh e
+fromList sh xx
+ = unsafePerformIO
+ $ do   let len = length xx
+        if len /= size sh
+         then error "Data.Array.Repa.Eval.Fill.fromList: provide array shape does not match list length"
+         else do
+                mvec    <- newMVec len
+                zipWithM_ (unsafeWriteMVec mvec) [0..] xx
+                unsafeFreezeMVec sh mvec
+
+
diff --git a/Data/Array/Repa/Operators/IndexSpace.hs b/Data/Array/Repa/Operators/IndexSpace.hs
--- a/Data/Array/Repa/Operators/IndexSpace.hs
+++ b/Data/Array/Repa/Operators/IndexSpace.hs
@@ -24,8 +24,8 @@
 -- Index space transformations ------------------------------------------------
 -- | Impose a new shape on the elements of an array.
 --   The new extent must be the same size as the original, else `error`.
-reshape	:: (Shape sh2, Shape sh1
-           , Repr r1 e)
+reshape	:: ( Shape sh1, Shape sh2
+           , Source r1 e)
 	=> sh2
 	-> Array r1 sh1 e
 	-> Array D  sh2 e
@@ -44,7 +44,7 @@
 -- | Append two arrays.
 append, (++)
 	:: ( Shape sh
-	   , Repr r1 e, Repr r2 e)
+           , Source r1 e, Source r2 e)
 	=> Array r1 (sh :. Int) e
 	-> Array r2 (sh :. Int) e
 	-> Array D  (sh :. Int) e
@@ -70,10 +70,9 @@
 -- | Transpose the lowest two dimensions of an array.
 --	Transposing an array twice yields the original.
 transpose
-	:: ( Shape sh
-	   , Repr r e)
-	=> Array r (sh :. Int :. Int) e
-	-> Array D (sh :. Int :. Int) e
+	:: (Shape sh, Source r e)
+	=> Array  r (sh :. Int :. Int) e
+	-> Array  D (sh :. Int :. Int) e
 
 transpose arr
  = unsafeTraverse arr
@@ -83,7 +82,7 @@
 
 
 -- | Extract a sub-range of elements from an array.
-extract :: (Shape sh, Repr r e)
+extract :: (Shape sh, Source r e)
         => sh                   -- ^ Starting index.
         -> sh                   -- ^ Size of result.
         -> Array r sh e 
@@ -97,8 +96,8 @@
 --	The result array has the same extent as the original.
 backpermute, unsafeBackpermute
 	:: forall r sh1 sh2 e
-	.  ( Shape sh1, Shape sh2
-	   , Repr r e)
+        .  ( Shape sh1, Shape sh2
+	   , Source r e)
 	=> sh2 			-- ^ Extent of result array.
 	-> (sh2 -> sh1) 	-- ^ Function mapping each index in the result array
 				--	to an index of the source array.
@@ -118,10 +117,10 @@
 --	If the function returns `Nothing` then the value at that index is taken
 --	from the default array (@arrDft@)
 backpermuteDft, unsafeBackpermuteDft
-	:: forall r0 r1 sh1 sh2 e
-	.  ( Shape sh1, Shape sh2
-	   , Repr  r0 e, Repr r1 e)
-	=> Array r0 sh2 e	-- ^ Default values (@arrDft@)
+	:: forall r1 r2 sh1 sh2 e
+        .  ( Shape sh1,   Shape sh2
+           , Source r1 e, Source r2 e)
+	=> Array r2 sh2 e	-- ^ Default values (@arrDft@)
 	-> (sh2 -> Maybe sh1) 	-- ^ Function mapping each index in the result array
 				--	to an index in the source array.
 	-> Array r1 sh1 e	-- ^ Source array.
@@ -153,9 +152,9 @@
 --
 extend, unsafeExtend
         :: ( Slice sl
-           , Shape (FullShape sl)
            , Shape (SliceShape sl)
-           , Repr r e)
+           , Shape (FullShape sl)
+           , Source r e)
         => sl
         -> Array r (SliceShape sl) e
         -> Array D (FullShape sl)  e
@@ -190,7 +189,7 @@
         :: ( Slice sl
            , Shape (FullShape sl)
            , Shape (SliceShape sl)
-           , Repr r e)
+           , Source r e)
         => Array r (FullShape sl) e
         -> sl
         -> Array D (SliceShape sl) e
diff --git a/Data/Array/Repa/Operators/Interleave.hs b/Data/Array/Repa/Operators/Interleave.hs
--- a/Data/Array/Repa/Operators/Interleave.hs
+++ b/Data/Array/Repa/Operators/Interleave.hs
@@ -5,13 +5,14 @@
 	, interleave3
 	, interleave4)
 where
+import Data.Array.Repa.Shape
 import Data.Array.Repa.Index
 import Data.Array.Repa.Base
 import Data.Array.Repa.Repr.Delayed
 import Data.Array.Repa.Operators.Traversal
-import Data.Array.Repa.Shape		as S
 import Prelude				hiding ((++))
 
+
 -- Interleave -----------------------------------------------------------------
 -- | Interleave the elements of two arrays.
 --   All the input arrays must have the same extent, else `error`.
@@ -23,8 +24,8 @@
 -- @
 --
 interleave2
-	:: (Shape sh
-	   , Repr r1 a, Repr r2 a)
+	:: ( Shape sh
+           , Source r1 a, Source r2 a)
 	=> Array r1 (sh :. Int) a
 	-> Array r2 (sh :. Int) a
 	-> Array D  (sh :. Int) a
@@ -51,7 +52,7 @@
 -- | Interleave the elements of three arrays.
 interleave3
 	:: ( Shape sh
-	   , Repr r1 a, Repr r2 a, Repr r3 a)
+           , Source r1 a, Source r2 a, Source r3 a)
 	=> Array r1 (sh :. Int) a
 	-> Array r2 (sh :. Int) a
 	-> Array r3 (sh :. Int) a
@@ -81,7 +82,7 @@
 -- | Interleave the elements of four arrays.
 interleave4
 	:: ( Shape sh
-	   , Repr r1 a, Repr r2 a, Repr r3 a, Repr r4 a)
+           , Source r1 a, Source r2 a, Source r3 a, Source r4 a)
 	=> Array r1 (sh :. Int) a
 	-> Array r2 (sh :. Int) a
 	-> Array r3 (sh :. Int) a
@@ -109,3 +110,5 @@
 		2	-> get3 (sh :. ix `div` 4)
 		3	-> get4 (sh :. ix `div` 4)
 		_	-> error "Data.Array.Repa.interleave4: this never happens :-P"
+
+
diff --git a/Data/Array/Repa/Operators/Mapping.hs b/Data/Array/Repa/Operators/Mapping.hs
--- a/Data/Array/Repa/Operators/Mapping.hs
+++ b/Data/Array/Repa/Operators/Mapping.hs
@@ -6,8 +6,8 @@
         , zipWith
         , (+^), (-^), (*^), (/^)
 
-          -- * Combining maps
-        , Combine(..))
+          -- * Structured maps
+        , Structured(..))
 where
 import Data.Array.Repa.Shape
 import Data.Array.Repa.Base
@@ -26,7 +26,7 @@
 -- | Apply a worker function to each element of an array, 
 --   yielding a new array with the same extent.
 --
-map     :: (Shape sh, Repr r a)
+map     :: (Shape sh, Source r a)
         => (a -> b) -> Array r sh a -> Array D sh b
 map f arr
  = case delay arr of
@@ -39,36 +39,35 @@
 --	If the extent of the two array arguments differ,
 --	then the resulting array's extent is their intersection.
 --
-zipWith :: (Shape sh, Repr r1 a, Repr r2 b)
+zipWith :: (Shape sh, Source r1 a, Source r2 b)
         => (a -> b -> c)
         -> Array r1 sh a -> Array r2 sh b
         -> Array D sh c
 zipWith f arr1 arr2
- = let  {-# INLINE get #-}
-        get ix  = f (arr1 `unsafeIndex` ix) (arr2 `unsafeIndex` ix)
-
+ = let  get ix  = f (arr1 `unsafeIndex` ix) (arr2 `unsafeIndex` ix)
+        {-# INLINE get #-}
+        
    in   fromFunction 
                 (intersectDim (extent arr1) (extent arr2)) 
                 get
 {-# INLINE [2] zipWith #-}
 
 
-{-# INLINE (+^) #-}
 (+^)	= zipWith (+)
+{-# INLINE (+^) #-}
 
-{-# INLINE (-^) #-}
 (-^)	= zipWith (-)
+{-# INLINE (-^) #-}
 
-{-# INLINE (*^) #-}
 (*^)	= zipWith (*)
+{-# INLINE (*^) #-}
 
-{-# INLINE (/^) #-}
 (/^)	= zipWith (/)
-
+{-# INLINE (/^) #-}
 
 
--- Combine --------------------------------------------------------------------
--- | Combining versions of @map@ and @zipWith@ that preserve the representation
+-- Structured -------------------------------------------------------------------
+-- | Structured versions of @map@ and @zipWith@ that preserve the representation
 --   of cursored and partitioned arrays. 
 --
 --   For cursored (@C@) arrays, the cursoring of the source array is preserved.
@@ -81,103 +80,115 @@
 --   is will make follow-on computation more efficient than if the array was
 --   converted to a vanilla Delayed (@D@) array as with plain `map` and `zipWith`.
 --
---   If the source array is not cursored or partitioned then `cmap` and 
---   `czipWith` are identical to the plain functions.
+--   If the source array is not cursored or partitioned then `smap` and 
+--   `szipWith` are identical to the plain functions.
 --
-class Combine r1 a r2 b | r1 -> r2 where
+class Structured r1 a b where
+ -- | The target result representation.
+ type TR r1
 
- -- | Combining @map@.
- cmap   :: Shape sh 
+ -- | Structured @map@.
+ smap   :: Shape sh 
         => (a -> b) 
-        -> Array r1 sh a 
-        -> Array r2 sh b
+        -> Array r1     sh a 
+        -> Array (TR r1) sh b
 
- -- | Combining @zipWith@.
+ -- | Structured @zipWith@.
  --   If you have a cursored or partitioned source array then use that as
  --   the third argument (corresponding to @r1@ here)
- czipWith
-        :: (Shape sh, Repr r c)
+ szipWith
+        :: (Shape sh, Source r c)
         => (c -> a -> b)
-        -> Array r  sh c
-        -> Array r1 sh a
-        -> Array r2 sh b
+        -> Array r      sh c
+        -> Array r1     sh a
+        -> Array (TR r1) sh b
 
 
 -- ByteString -------------------------
-instance Combine B Word8 D b where
- cmap           = map
- czipWith       = zipWith
+instance Structured B Word8 b where
+ type TR B = D
+ smap           = map
+ szipWith       = zipWith
 
 
 -- Cursored ---------------------------
-instance Combine C a C b where
- {-# INLINE [3] cmap #-}
- cmap f (ACursored sh makec shiftc loadc)
-        = ACursored sh makec shiftc (f . loadc)
+instance Structured C a b where
+ type TR C = C
 
- {-# INLINE [2] czipWith #-}
- czipWith f arr1 (ACursored sh makec shiftc loadc)
-  = let {-# INLINE makec' #-}
-        makec' ix               = (ix, makec ix)
+ smap f (ACursored sh makec shiftc loadc)
+        = ACursored sh makec shiftc (f . loadc)
+ {-# INLINE [3] smap #-}
 
-        {-# INLINE shiftc' #-}
+ szipWith f arr1 (ACursored sh makec shiftc loadc)
+  = let makec' ix               = (ix, makec ix)
+        {-# INLINE makec' #-}
+        
         shiftc' off (ix, cur)   = (addDim off ix, shiftc off cur)
+        {-# INLINE shiftc' #-}
 
-        {-# INLINE load' #-}
         load' (ix, cur)         = f (arr1 `unsafeIndex` ix) (loadc cur)
+        {-# INLINE load' #-}
 
     in  ACursored 
                 (intersectDim (extent arr1) sh)
                 makec' shiftc' load'
+ {-# INLINE [2] szipWith #-}
 
 
 -- Delayed ----------------------------
-instance Combine D a D b where
- cmap           = map
- czipWith       = zipWith
+instance Structured D a b where
+ type TR D = D
+ smap           = map
+ szipWith       = zipWith
 
 
 -- ForeignPtr -------------------------
-instance Storable a => Combine F a D b where
- cmap           = map
- czipWith       = zipWith
+instance Storable a => Structured F a b where
+ type TR F = D
+ smap           = map
+ szipWith       = zipWith
 
 
 -- Partitioned ------------------------
-instance (Combine r11 a r21 b
-        , Combine r12 a r22 b)
-       => Combine (P r11 r12) a (P r21 r22) b where
+instance (Structured r1 a b
+        , Structured r2 a b)
+       => Structured (P r1 r2) a b where
+ type TR (P r1 r2) = P (TR r1) (TR r2)
 
- cmap f (APart sh range arr1 arr2)
-        = APart sh range (cmap f arr1) (cmap f arr2)
- {-# INLINE [3] cmap #-}
+ smap f (APart sh range arr1 arr2)
+        = APart sh range (smap f arr1) (smap f arr2)
+ {-# INLINE [3] smap #-}
 
- czipWith f arr1 (APart sh range arr21 arr22)
-        = APart sh range (czipWith f arr1 arr21)
-                         (czipWith f arr1 arr22)
- {-# INLINE [2] czipWith #-}
+ szipWith f arr1 (APart sh range arr21 arr22)
+        = APart sh range (szipWith f arr1 arr21)
+                         (szipWith f arr1 arr22)
+ {-# INLINE [2] szipWith #-}
 
 
 -- Small ------------------------------
-instance   Combine r1 a r2 b
-        => Combine (S r1) a (S r2) b where
- cmap f (ASmall arr1)
-        = ASmall (cmap f arr1)
- {-# INLINE [3] cmap #-}
+instance   Structured r1 a b
+        => Structured (S r1) a b where
+ type TR (S r1) = S (TR r1)
 
- czipWith f arr1 (ASmall arr2)
-        = ASmall (czipWith f arr1 arr2)
- {-# INLINE [3] czipWith #-}
+ smap f (ASmall arr1)
+        = ASmall (smap f arr1)
+ {-# INLINE [3] smap #-}
 
+ szipWith f arr1 (ASmall arr2)
+        = ASmall (szipWith f arr1 arr2)
+ {-# INLINE [3] szipWith #-}
 
+
 -- Unboxed ----------------------------
-instance Unbox a => Combine U a D b where
- cmap           = map
- czipWith       = zipWith
+instance Unbox a => Structured U a b where
+ type TR U = D
+ smap           = map
+ szipWith       = zipWith
 
 
 -- Undefined --------------------------
-instance Combine X a X b where
- cmap     _   (AUndefined sh) = AUndefined sh
- czipWith _ _ (AUndefined sh) = AUndefined sh
+instance Structured X a b where
+ type TR X = X
+ smap     _   (AUndefined sh) = AUndefined sh
+ szipWith _ _ (AUndefined sh) = AUndefined sh
 
diff --git a/Data/Array/Repa/Operators/Reduction.hs b/Data/Array/Repa/Operators/Reduction.hs
--- a/Data/Array/Repa/Operators/Reduction.hs
+++ b/Data/Array/Repa/Operators/Reduction.hs
@@ -24,7 +24,7 @@
 -- | Sequential reduction of the innermost dimension of an arbitrary rank array.
 --
 --   Combine this with `transpose` to fold any other dimension.
-foldS   :: (Shape sh, Elt a, Unbox a, Repr r a)
+foldS   :: (Shape sh, Source r a, Elt a, Unbox a)
         => (a -> a -> a)
         -> a
         -> Array r (sh :. Int) a
@@ -49,8 +49,7 @@
 --   example @0@ is neutral with respect to @(+)@ as @0 + a = a@.
 --   These restrictions are required to support parallel evaluation, as the
 --   starting element may be used multiple times depending on the number of threads.
-foldP   
-        :: (Shape sh, Elt a, Unbox a, Repr r a, Monad m)
+foldP   :: (Shape sh, Source r a, Elt a, Unbox a, Monad m)
         => (a -> a -> a)
         -> a
         -> Array r (sh :. Int) a
@@ -80,7 +79,7 @@
 -- foldAll --------------------------------------------------------------------
 -- | Sequential reduction of an array of arbitrary rank to a single scalar value.
 --
-foldAllS :: (Shape sh, Elt a, Unbox a, Repr r a)
+foldAllS :: (Shape sh, Source r a, Elt a, Unbox a)
 	=> (a -> a -> a)
 	-> a
 	-> Array r sh a
@@ -104,7 +103,7 @@
 --   These restrictions are required to support parallel evaluation, as the
 --   starting element may be used multiple times depending on the number of threads.
 foldAllP 
-        :: (Shape sh, Elt a, Unbox a, Repr r a, Monad m)
+        :: (Shape sh, Source r a, Elt a, Unbox a, Monad m)
 	=> (a -> a -> a)
 	-> a
 	-> Array r sh a
@@ -122,7 +121,7 @@
 
 -- sum ------------------------------------------------------------------------
 -- | Sequential sum the innermost dimension of an array.
-sumS	:: (Shape sh, Num a, Elt a, Unbox a, Repr r a)
+sumS	:: (Shape sh, Source r a, Num a, Elt a, Unbox a)
 	=> Array r (sh :. Int) a
 	-> Array U sh a
 sumS = foldS (+) 0
@@ -130,7 +129,7 @@
 
 
 -- | Parallel sum the innermost dimension of an array.
-sumP	:: (Shape sh, Num a, Elt a, Unbox a, Repr r a, Monad m)
+sumP	:: (Shape sh, Source r a, Num a, Elt a, Unbox a, Monad m)
 	=> Array r (sh :. Int) a
 	-> m (Array U sh a)
 sumP = foldP (+) 0 
@@ -139,7 +138,7 @@
 
 -- sumAll ---------------------------------------------------------------------
 -- | Sequential sum of all the elements of an array.
-sumAllS	:: (Shape sh, Elt a, Unbox a, Num a, Repr r a)
+sumAllS	:: (Shape sh, Source r a, Elt a, Unbox a, Num a)
 	=> Array r sh a
 	-> a
 sumAllS = foldAllS (+) 0
@@ -147,7 +146,7 @@
 
 
 -- | Parallel sum all the elements of an array.
-sumAllP	:: (Shape sh, Elt a, Unbox a, Num a, Repr r a, Monad m)
+sumAllP	:: (Shape sh, Source r a, Elt a, Unbox a, Num a, Monad m)
 	=> Array r sh a
 	-> m a
 sumAllP = foldAllP (+) 0
@@ -155,7 +154,7 @@
 
 
 -- Equality ------------------------------------------------------------------
-instance (Shape sh, Repr r e, Eq e) => Eq (Array r sh e) where
+instance (Shape sh, Eq sh, Source r a, Eq a) => Eq (Array r sh a) where
  (==) arr1 arr2
         =   extent arr1 == extent arr2
         && (foldAllS (&&) True (R.zipWith (==) arr1 arr2))
@@ -163,9 +162,9 @@
 
 -- | Check whether two arrays have the same shape and contain equal elements,
 --   in parallel.
-equalsP :: (Shape sh, Repr r1 e, Repr r2 e, Eq e, Monad m) 
-        => Array r1 sh e 
-        -> Array r2 sh e
+equalsP :: (Shape sh, Eq sh, Source r1 a, Source r2 a, Eq a, Monad m) 
+        => Array r1 sh a 
+        -> Array r2 sh a
         -> m Bool
 equalsP arr1 arr2
  = do   same    <- foldAllP (&&) True (R.zipWith (==) arr1 arr2)
@@ -174,9 +173,9 @@
 
 -- | Check whether two arrays have the same shape and contain equal elements,
 --   sequentially.
-equalsS :: (Shape sh, Repr r1 e, Repr r2 e, Eq e) 
-        => Array r1 sh e 
-        -> Array r2 sh e
+equalsS :: (Shape sh, Eq sh, Source r1 a, Source r2 a, Eq a) 
+        => Array r1 sh a 
+        -> Array r2 sh a
         -> Bool
 equalsS arr1 arr2
         =   extent arr1 == extent arr2
diff --git a/Data/Array/Repa/Operators/Traversal.hs b/Data/Array/Repa/Operators/Traversal.hs
--- a/Data/Array/Repa/Operators/Traversal.hs
+++ b/Data/Array/Repa/Operators/Traversal.hs
@@ -13,7 +13,8 @@
 -- | Unstructured traversal.
 traverse, unsafeTraverse
 	:: forall r sh sh' a b
-	.  (Shape sh, Shape sh', Repr r a)
+	.  ( Source r a
+           , Shape sh, Shape sh')
 	=> Array r sh a		        -- ^ Source array.
 	-> (sh  -> sh')			-- ^ Function to produce the extent of the result.
 	-> ((sh -> a) -> sh' -> b)	-- ^ Function to produce elements of the result.
@@ -32,8 +33,8 @@
 -- | Unstructured traversal over two arrays at once.
 traverse2, unsafeTraverse2
 	:: forall r1 r2 sh sh' sh'' a b c
-	.  ( Shape sh,  Shape sh', Shape sh''
-	   , Repr r1 a, Repr r2 b)
+	.  ( Source r1 a, Source r2 b
+           , Shape sh, Shape sh', Shape sh'')
         => Array r1 sh  a 		-- ^ First source array.
 	-> Array r2 sh' b		-- ^ Second source array.
         -> (sh -> sh' -> sh'')		-- ^ Function to produce the extent of the result.
@@ -59,8 +60,8 @@
 	:: forall r1  r2  r3
 	          sh1 sh2 sh3 sh4
 	          a   b   c   d
-	.  ( Shape sh1, Shape sh2, Shape sh3, Shape sh4
-	   , Repr r1 a, Repr r2 b, Repr r3 c)
+	.  ( Source r1 a, Source r2 b, Source r3 c
+           , Shape sh1,   Shape sh2,   Shape sh3,   Shape sh4)
         => Array r1 sh1 a
 	-> Array r2 sh2 b
 	-> Array r3 sh3 c
@@ -86,8 +87,8 @@
 	:: forall r1  r2  r3  r4
 	          sh1 sh2 sh3 sh4 sh5
 	          a   b   c   d   e
-	.  ( Shape sh1, Shape sh2, Shape sh3, Shape sh4, Shape sh5
-	   , Repr r1 a, Repr r2 b, Repr r3 c, Repr r4 d)
+	.  ( Source r1 a, Source r2 b, Source r3 c, Source r4 d
+           , Shape sh1, Shape sh2, Shape sh3, Shape sh4, Shape sh5)
         => Array r1 sh1 a
 	-> Array r2 sh2 b
 	-> Array r3 sh3 c
diff --git a/Data/Array/Repa/Repr/ByteString.hs b/Data/Array/Repa/Repr/ByteString.hs
--- a/Data/Array/Repa/Repr/ByteString.hs
+++ b/Data/Array/Repa/Repr/ByteString.hs
@@ -14,19 +14,12 @@
 
 -- | Strict ByteStrings arrays are represented as ForeignPtr buffers of Word8
 data B
-data instance Array B sh Word8
-        = AByteString !sh !ByteString
         
-deriving instance Show sh
-        => Show (Array B sh Word8)
-
-deriving instance Read sh
-        => Read (Array B sh Word8)
-
-
--- Repr -----------------------------------------------------------------------
 -- | Read elements from a `ByteString`.
-instance Repr B Word8 where
+instance Source B Word8 where
+ data Array B sh Word8
+        = AByteString !sh !ByteString
+
  linearIndex (AByteString _ bs) ix
         = bs `B.index` ix
  {-# INLINE linearIndex #-}
@@ -42,6 +35,13 @@
  deepSeqArray (AByteString sh bs) x 
   = sh `deepSeq` bs `seq` x
  {-# INLINE deepSeqArray #-}
+
+
+deriving instance Show sh
+        => Show (Array B sh Word8)
+
+deriving instance Read sh
+        => Read (Array B sh Word8)
 
 
 -- Conversions ----------------------------------------------------------------
diff --git a/Data/Array/Repa/Repr/Cursored.hs b/Data/Array/Repa/Repr/Cursored.hs
--- a/Data/Array/Repa/Repr/Cursored.hs
+++ b/Data/Array/Repa/Repr/Cursored.hs
@@ -8,9 +8,10 @@
 import Data.Array.Repa.Index
 import Data.Array.Repa.Repr.Delayed
 import Data.Array.Repa.Repr.Undefined
-import Data.Array.Repa.Eval.Fill
+import Data.Array.Repa.Eval.Load
 import Data.Array.Repa.Eval.Elt
 import Data.Array.Repa.Eval.Cursored
+import Data.Array.Repa.Eval.Target
 import GHC.Exts
 import Debug.Trace
 
@@ -23,23 +24,24 @@
 --   array representation has changed since this paper was published.
 data C
 
-data instance Array C sh e
+
+-- | Compute elements of a cursored array.
+instance Source C a where
+
+ data Array C sh a
         = forall cursor. ACursored
         { cursoredExtent :: !sh 
                 
           -- | Make a cursor to a particular element.
-	, makeCursor     :: sh -> cursor
+        , makeCursor     :: sh -> cursor
 
-	  -- | Shift the cursor by an offset, to get to another element.
-	, shiftCursor    :: sh -> cursor -> cursor
+          -- | Shift the cursor by an offset, to get to another element.
+        , shiftCursor    :: sh -> cursor -> cursor
 
-	  -- | Load\/compute the element at the given cursor.
-	, loadCursor	 :: cursor -> e }
+          -- | Load\/compute the element at the given cursor.
+        , loadCursor     :: cursor -> a }
 
 
--- Repr -----------------------------------------------------------------------
--- | Compute elements of a cursored array.
-instance Repr C a where
  index (ACursored _ makec _ loadc)
         = loadc . makec
  {-# INLINE index #-}
@@ -62,52 +64,52 @@
 
 -- Fill -----------------------------------------------------------------------
 -- | Compute all elements in an rank-2 array. 
-instance (Fillable r2 e, Elt e) => Fill C r2 DIM2 e where
- fillP (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr
-  = do  traceEventIO "Repa.fillP[Cursored]: start"
+instance Elt e => Load C DIM2 e where
+ loadP (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr
+  = do  traceEventIO "Repa.loadP[Cursored]: start"
         fillCursoredBlock2P 
-                (unsafeWriteMArr marr) 
+                (unsafeWriteMVec marr) 
                 makec shiftc loadc
                 w 0# 0# w h
-        touchMArr marr
-        traceEventIO "Repa.fillP[Cursored]: end"
- {-# INLINE fillP #-}
+        touchMVec marr
+        traceEventIO "Repa.loadP[Cursored]: end"
+ {-# INLINE loadP #-}
         
- fillS (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr
-  = do  traceEventIO "Repa.fillS[Cursored]: start"
+ loadS (ACursored (Z :. (I# h) :. (I# w)) makec shiftc loadc) marr
+  = do  traceEventIO "Repa.loadS[Cursored]: start"
         fillCursoredBlock2S 
-                (unsafeWriteMArr marr) 
+                (unsafeWriteMVec marr) 
                 makec shiftc loadc
                 w 0# 0# w h
-        touchMArr marr
-        traceEventIO "Repa.fillS[Cursored]: end"
- {-# INLINE fillS #-}
+        touchMVec marr
+        traceEventIO "Repa.loadS[Cursored]: end"
+ {-# INLINE loadS #-}
         
 
 -- | Compute a range of elements in a rank-2 array.
-instance (Fillable r2 e, Elt e) => FillRange C r2 DIM2 e where
- fillRangeP  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr
+instance Elt e => LoadRange C DIM2 e where
+ loadRangeP  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr
              (Z :. (I# y0) :. (I# x0)) (Z :. (I# h0) :. (I# w0))
-  = do  traceEventIO "Repa.fillRangeP[Cursored]: start"
+  = do  traceEventIO "Repa.loadRangeP[Cursored]: start"
         fillCursoredBlock2P 
-                (unsafeWriteMArr marr) 
+                (unsafeWriteMVec marr) 
                 makec shiftc loadc
                 w x0 y0 w0 h0
-        touchMArr marr
-        traceEventIO "Repa.fillRangeP[Cursored]: end"
- {-# INLINE fillRangeP #-}
+        touchMVec marr
+        traceEventIO "Repa.loadRangeP[Cursored]: end"
+ {-# INLINE loadRangeP #-}
         
- fillRangeS  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr
+ loadRangeS  (ACursored (Z :. _h :. (I# w)) makec shiftc loadc) marr
              (Z :. (I# y0) :. (I# x0)) 
              (Z :. (I# h0) :. (I# w0))
-  = do  traceEventIO "Repa.fillRangeS[Cursored]: start"
+  = do  traceEventIO "Repa.loadRangeS[Cursored]: start"
         fillCursoredBlock2S
-                (unsafeWriteMArr marr) 
+                (unsafeWriteMVec marr) 
                 makec shiftc loadc
                 w x0 y0 w0 h0
-        touchMArr marr
-        traceEventIO "Repa.fillRangeS[Cursored]: end"
- {-# INLINE fillRangeS #-}
+        touchMVec marr
+        traceEventIO "Repa.loadRangeS[Cursored]: end"
+ {-# INLINE loadRangeS #-}
         
 
 -- Conversions ----------------------------------------------------------------
diff --git a/Data/Array/Repa/Repr/Delayed.hs b/Data/Array/Repa/Repr/Delayed.hs
--- a/Data/Array/Repa/Repr/Delayed.hs
+++ b/Data/Array/Repa/Repr/Delayed.hs
@@ -4,10 +4,11 @@
         , fromFunction, toFunction
         , delay)
 where
-import Data.Array.Repa.Eval.Elt
-import Data.Array.Repa.Eval.Cursored
+import Data.Array.Repa.Eval.Load
+import Data.Array.Repa.Eval.Target
 import Data.Array.Repa.Eval.Chunked
-import Data.Array.Repa.Eval.Fill
+import Data.Array.Repa.Eval.Cursored
+import Data.Array.Repa.Eval.Elt
 import Data.Array.Repa.Index
 import Data.Array.Repa.Shape
 import Data.Array.Repa.Base
@@ -19,15 +20,14 @@
 --   Every time you index into a delayed array the element at that position 
 --   is recomputed.
 data D
-data instance Array D sh e
+
+-- | Compute elements of a delayed array.
+instance Source D a where
+ data Array D sh a
         = ADelayed  
                 !sh 
-                (sh -> e) 
-
+                (sh -> a) 
 
--- Repr -----------------------------------------------------------------------
--- | Compute elements of a delayed array.
-instance Repr D a where
  index       (ADelayed _  f) ix  = f ix
  {-# INLINE index #-}
 
@@ -43,50 +43,49 @@
  {-# INLINE deepSeqArray #-}
 
 
--- Fill -----------------------------------------------------------------------
+-- Load -----------------------------------------------------------------------
 -- | Compute all elements in an array.
-instance (Fillable r2 e, Shape sh) => Fill D r2 sh e where
- fillP (ADelayed sh getElem) marr
-  = marr `deepSeqMArr` 
-    do  traceEventIO "Repa.fillP[Delayed]: start"
-        fillChunkedP (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh) 
-        touchMArr marr
-        traceEventIO "Repa.fillP[Delayed]: end"
- {-# INLINE [4] fillP #-}
-
- fillS (ADelayed sh getElem) marr
-  = marr `deepSeqMArr` 
-    do  traceEventIO "Repa.fillS[Delayed]: start"
-        fillChunkedS (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh)
-        touchMArr marr
-        traceEventIO "Repa.fillS[Delayed]: end"
+instance Shape sh => Load D sh e where
+ loadP (ADelayed sh getElem) mvec
+  = mvec `deepSeqMVec` 
+    do  traceEventIO "Repa.loadP[Delayed]: start"
+        fillChunkedP (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh) 
+        touchMVec mvec
+        traceEventIO "Repa.loadP[Delayed]: end"
+ {-# INLINE [4] loadP #-}
 
- {-# INLINE [4] fillS #-}
+ loadS (ADelayed sh getElem) mvec
+  = mvec `deepSeqMVec` 
+    do  traceEventIO "Repa.loadS[Delayed]: start"
+        fillChunkedS (size sh) (unsafeWriteMVec mvec) (getElem . fromIndex sh)
+        touchMVec mvec
+        traceEventIO "Repa.loadS[Delayed]: end"
+ {-# INLINE [4] loadS #-}
 
 
 -- | Compute a range of elements in a rank-2 array.
-instance (Fillable r2 e, Elt e) => FillRange D r2 DIM2 e where
- fillRangeP  (ADelayed (Z :. _h :. (I# w)) getElem) marr
+instance Elt e => LoadRange D DIM2 e where
+ loadRangeP  (ADelayed (Z :. _h :. (I# w)) getElem) mvec
              (Z :. (I# y0) :. (I# x0)) (Z :. (I# h0) :. (I# w0))
-  = marr `deepSeqMArr` 
-    do  traceEventIO "Repa.fillRangeP[Delayed]: start"
-        fillBlock2P (unsafeWriteMArr marr) 
+  = mvec `deepSeqMVec` 
+    do  traceEventIO "Repa.loadRangeP[Delayed]: start"
+        fillBlock2P (unsafeWriteMVec mvec) 
                         getElem
                         w x0 y0 w0 h0
-        touchMArr marr
-        traceEventIO "Repa.fillRangeP[Delayed]: end"
- {-# INLINE [1] fillRangeP #-}
+        touchMVec mvec
+        traceEventIO "Repa.loadRangeP[Delayed]: end"
+ {-# INLINE [1] loadRangeP #-}
 
- fillRangeS  (ADelayed (Z :. _h :. (I# w)) getElem) marr
+ loadRangeS  (ADelayed (Z :. _h :. (I# w)) getElem) mvec
              (Z :. (I# y0) :. (I# x0)) (Z :. (I# h0) :. (I# w0))
-  = marr `deepSeqMArr`
-    do  traceEventIO "Repa.fillRangeS[Delayed]: start"
-        fillBlock2S (unsafeWriteMArr marr) 
+  = mvec `deepSeqMVec`
+    do  traceEventIO "Repa.loadRangeS[Delayed]: start"
+        fillBlock2S (unsafeWriteMVec mvec) 
                 getElem
                 w x0 y0 w0 h0
-        touchMArr marr
-        traceEventIO "Repa.fillRangeS[Delayed]: end"
- {-# INLINE [1] fillRangeS #-}
+        touchMVec mvec
+        traceEventIO "Repa.loadRangeS[Delayed]: end"
+ {-# INLINE [1] loadRangeS #-}
 
 
 -- Conversions ----------------------------------------------------------------
@@ -100,7 +99,7 @@
 -- | O(1). Produce the extent of an array, and a function to retrieve an
 --   arbitrary element.
 toFunction 
-        :: (Shape sh, Repr r1 a)
+        :: (Shape sh, Source r1 a)
         => Array r1 sh a -> (sh, sh -> a)
 toFunction arr
  = case delay arr of
@@ -113,7 +112,7 @@
 --   indices to elements, so consumers don't need to worry about
 --   what the previous representation was.
 --
-delay   :: (Shape sh, Repr r e)
+delay   :: Shape sh => Source r e
         => Array r sh e -> Array D sh e
 delay arr = ADelayed (extent arr) (unsafeIndex arr)
 {-# INLINE delay #-}
diff --git a/Data/Array/Repa/Repr/ForeignPtr.hs b/Data/Array/Repa/Repr/ForeignPtr.hs
--- a/Data/Array/Repa/Repr/ForeignPtr.hs
+++ b/Data/Array/Repa/Repr/ForeignPtr.hs
@@ -6,7 +6,8 @@
 where
 import Data.Array.Repa.Shape
 import Data.Array.Repa.Base
-import Data.Array.Repa.Eval.Fill
+import Data.Array.Repa.Eval.Load
+import Data.Array.Repa.Eval.Target
 import Data.Array.Repa.Repr.Delayed
 import Foreign.Storable
 import Foreign.ForeignPtr
@@ -16,13 +17,12 @@
 
 -- | Arrays represented as foreign buffers in the C heap.
 data F
-data instance Array F sh e
-        = AForeignPtr !sh !Int !(ForeignPtr e)
 
-
--- Repr -----------------------------------------------------------------------
 -- | Read elements from a foreign buffer.
-instance Storable a => Repr F a where
+instance Storable a => Source F a where
+ data Array F sh a
+        = AForeignPtr !sh !Int !(ForeignPtr a)
+
  linearIndex (AForeignPtr _ len fptr) ix
   | ix < len  
         = unsafePerformIO 
@@ -48,38 +48,38 @@
  {-# INLINE deepSeqArray #-}
  
 
--- Fill -----------------------------------------------------------------------
--- | Filling of foreign buffers.
-instance Storable e => Fillable F e where
- data MArr F e 
-  = FPArr !Int !(ForeignPtr e)
+-- Load -----------------------------------------------------------------------
+-- | Filling foreign buffers.
+instance Storable e => Target F e where
+ data MVec F e 
+  = FPVec !Int !(ForeignPtr e)
 
- newMArr n
+ newMVec n
   = do  let (proxy :: e) = undefined
         ptr              <- mallocBytes (sizeOf proxy * n)
         _                <- peek ptr  `asTypeOf` return proxy
         
         fptr             <- newForeignPtr finalizerFree ptr
-        return           $ FPArr n fptr
- {-# INLINE newMArr #-}
+        return           $ FPVec n fptr
+ {-# INLINE newMVec #-}
 
  -- CAREFUL: Unwrapping the foreignPtr like this means we need to be careful
  -- to touch it after the last use, otherwise the finaliser might run too early.
- unsafeWriteMArr (FPArr _ fptr) !ix !x
+ unsafeWriteMVec (FPVec _ fptr) !ix !x
   = pokeElemOff (Unsafe.unsafeForeignPtrToPtr fptr) ix x
- {-# INLINE unsafeWriteMArr #-}
+ {-# INLINE unsafeWriteMVec #-}
 
- unsafeFreezeMArr !sh (FPArr len fptr)     
+ unsafeFreezeMVec !sh (FPVec len fptr)
   =     return  $ AForeignPtr sh len fptr
- {-# INLINE unsafeFreezeMArr #-}
+ {-# INLINE unsafeFreezeMVec #-}
 
- deepSeqMArr !(FPArr _ fptr) x
+ deepSeqMVec !(FPVec _ fptr) x
   = Unsafe.unsafeForeignPtrToPtr fptr `seq` x
- {-# INLINE deepSeqMArr #-}
+ {-# INLINE deepSeqMVec #-}
 
- touchMArr (FPArr _ fptr)
+ touchMVec (FPVec _ fptr)
   = touchForeignPtr fptr
- {-# INLINE touchMArr #-}
+ {-# INLINE touchMVec #-}
 
 
 -- Conversions ----------------------------------------------------------------
@@ -103,10 +103,10 @@
 --   buffer without intermediate copying. If you want to copy a
 --   pre-existing manifest array to a foreign buffer then `delay` it first.
 computeIntoS
-        :: Fill r1 F sh e
+        :: (Load r1 sh e, Storable e)
         => ForeignPtr e -> Array r1 sh e -> IO ()
 computeIntoS !fptr !arr
- = fillS arr (FPArr 0 fptr)
+ = loadS arr (FPVec 0 fptr)
 {-# INLINE computeIntoS #-}
 
 
@@ -114,9 +114,9 @@
 --   buffer without intermediate copying. If you want to copy a
 --   pre-existing manifest array to a foreign buffer then `delay` it first.
 computeIntoP
-        :: Fill r1 F sh e
+        :: (Load r1 sh e, Storable e)
         => ForeignPtr e -> Array r1 sh e -> IO ()
 computeIntoP !fptr !arr
- = fillP arr (FPArr 0 fptr)
+ = loadP arr (FPVec 0 fptr)
 {-# INLINE computeIntoP #-}
 
diff --git a/Data/Array/Repa/Repr/HintInterleave.hs b/Data/Array/Repa/Repr/HintInterleave.hs
--- a/Data/Array/Repa/Repr/HintInterleave.hs
+++ b/Data/Array/Repa/Repr/HintInterleave.hs
@@ -2,7 +2,8 @@
 module Data.Array.Repa.Repr.HintInterleave
         (I, Array (..), hintInterleave)
 where
-import Data.Array.Repa.Eval.Fill
+import Data.Array.Repa.Eval.Load
+import Data.Array.Repa.Eval.Target
 import Data.Array.Repa.Eval.Interleaved
 import Data.Array.Repa.Repr.Delayed
 import Data.Array.Repa.Shape
@@ -14,22 +15,10 @@
 --   and evaluation should be interleaved between the processors.
 data I r1
 
-data instance Array (I r1) sh e
-        = AInterleave !(Array r1 sh e)
-
-deriving instance Show (Array r1 sh e) 
-        => Show (Array (I r1) sh e)
-
-deriving instance Read (Array r1 sh e) 
-        => Read (Array (I r1) sh e)
-
-
--- | Wrap an array with a unbalanced-ness hint.
-hintInterleave :: Array r1 sh e -> Array (I r1) sh e
-hintInterleave = AInterleave
-
+instance Source r1 a => Source (I r1) a where
+ data Array (I r1) sh a
+        = AInterleave !(Array r1 sh a)
 
-instance Repr r1 a => Repr (I r1) a where
  extent (AInterleave arr) 
         = extent arr
  {-# INLINE extent #-}
@@ -55,20 +44,33 @@
  {-# INLINE deepSeqArray #-}
 
 
--- Fill -----------------------------------------------------------------------
-instance ( Shape sh, Fill D r2 sh e) 
-        => Fill (I D) r2 sh e where
- fillP (AInterleave (ADelayed sh getElem)) marr
-  = marr `deepSeqMArr`
-    do  traceEventIO "Repa.fillP[Interleaved]: start"
-        fillInterleavedP (size sh) (unsafeWriteMArr marr) (getElem . fromIndex sh) 
-        touchMArr marr
-        traceEventIO "Repa.fillP[Interleaved]: end"
- {-# INLINE [4] fillP #-}
+deriving instance Show (Array r1 sh e) 
+        => Show (Array (I r1) sh e)
 
+deriving instance Read (Array r1 sh e) 
+        => Read (Array (I r1) sh e)
+
+
+-- | Wrap an array with a unbalanced-ness hint.
+hintInterleave :: Array r1 sh e -> Array (I r1) sh e
+hintInterleave = AInterleave
+
+
+-- Load -----------------------------------------------------------------------
+instance (Shape sh, Load D sh e) 
+        => Load (I D) sh e where
+ loadP (AInterleave (ADelayed sh getElem)) marr
+  = marr `deepSeqMVec`
+    do  traceEventIO "Repa.loadP[Interleaved]: start"
+        fillInterleavedP (size sh) (unsafeWriteMVec marr) (getElem . fromIndex sh) 
+        touchMVec marr
+        traceEventIO "Repa.loadP[Interleaved]: end"
+ {-# INLINE [4] loadP #-}
+
  -- The fact that the workload is unbalanced doesn't affect us when the
  -- program is run sequentially, so just use the filling method of the inner
  -- representation
- fillS (AInterleave arr) marr
-  = fillS arr marr
- {-# INLINE fillS #-}
+ loadS (AInterleave arr) marr
+  = loadS arr marr
+ {-# INLINE loadS #-}
+
diff --git a/Data/Array/Repa/Repr/HintSmall.hs b/Data/Array/Repa/Repr/HintSmall.hs
--- a/Data/Array/Repa/Repr/HintSmall.hs
+++ b/Data/Array/Repa/Repr/HintSmall.hs
@@ -2,31 +2,20 @@
 module Data.Array.Repa.Repr.HintSmall
         (S, Array (..), hintSmall)
 where
+import Data.Array.Repa.Eval.Load
 import Data.Array.Repa.Base
-import Data.Array.Repa.Eval.Fill
 import Data.Array.Repa.Shape
 
+
 -- | Hints that evaluating this array is only a small amount of work.
 --   It will be evaluated sequentially in the main thread, instead of
 --   in parallel on the gang. This avoids the associated scheduling overhead.
 data S r1
 
-data instance Array (S r1) sh e
-        = ASmall !(Array r1 sh e)
-
-deriving instance Show (Array r1 sh e) 
-        => Show (Array (S r1) sh e)
-
-deriving instance Read (Array r1 sh e) 
-        => Read (Array (S r1) sh e)
-
-
--- | Wrap an array with a smallness hint.
-hintSmall :: Array r1 sh e -> Array (S r1) sh e
-hintSmall = ASmall
-
+instance Source r1 a => Source (S r1) a where
+ data Array (S r1) sh a
+        = ASmall !(Array r1 sh a)
 
-instance Repr r1 a => Repr (S r1) a where
  extent (ASmall arr) 
         = extent arr
  {-# INLINE extent #-}
@@ -52,25 +41,37 @@
  {-# INLINE deepSeqArray #-}
 
 
--- Fill -----------------------------------------------------------------------
-instance ( Shape sh, Fill r1 r2 sh e) 
-        => Fill (S r1) r2 sh e where
- fillP (ASmall arr) marr
-  = fillS arr marr
- {-# INLINE fillP #-}
+-- | Wrap an array with a smallness hint.
+hintSmall :: Array r1 sh e -> Array (S r1) sh e
+hintSmall = ASmall
 
- fillS (ASmall arr) marr
-  = fillS arr marr
- {-# INLINE fillS #-}
 
+deriving instance Show (Array r1 sh e) 
+        => Show (Array (S r1) sh e)
 
--- FillRange ------------------------------------------------------------------
-instance ( Shape sh, FillRange r1 r2 sh e)
-        => FillRange (S r1) r2 sh e where
- fillRangeP (ASmall arr) marr ix1 ix2
-  = fillRangeS arr marr ix1 ix2
- {-# INLINE fillRangeP #-}
+deriving instance Read (Array r1 sh e) 
+        => Read (Array (S r1) sh e)
 
- fillRangeS (ASmall arr) marr ix1 ix2
-  = fillRangeS arr marr ix1 ix2
- {-# INLINE fillRangeS #-}
+
+-- Load ----------------------------------------------------------------------
+instance ( Shape sh, Load r1 sh e) 
+        => Load (S r1) sh e where
+ loadP (ASmall arr) marr
+  = loadS arr marr
+ {-# INLINE loadP #-}
+
+ loadS (ASmall arr) marr
+  = loadS arr marr
+ {-# INLINE loadS #-}
+
+
+-- LoadRange ------------------------------------------------------------------
+instance ( Shape sh, LoadRange r1 sh e)
+        => LoadRange (S r1) sh e where
+ loadRangeP (ASmall arr) marr ix1 ix2
+  = loadRangeS arr marr ix1 ix2
+ {-# INLINE loadRangeP #-}
+
+ loadRangeS (ASmall arr) marr ix1 ix2
+  = loadRangeS arr marr ix1 ix2
+ {-# INLINE loadRangeS #-}
diff --git a/Data/Array/Repa/Repr/Partitioned.hs b/Data/Array/Repa/Repr/Partitioned.hs
--- a/Data/Array/Repa/Repr/Partitioned.hs
+++ b/Data/Array/Repa/Repr/Partitioned.hs
@@ -23,11 +23,6 @@
 --
 data P r1 r2
 
-data instance Array (P r1 r2) sh e
-        = APart !sh                          -- size of the whole array
-                !(Range sh) !(Array r1 sh e) -- if in range use this array
-                !(Array r2 sh e)             -- otherwise use this array
-
 data Range sh
         = Range !sh !sh                      -- indices defining the range
                 (sh -> Bool)                 -- predicate to check whether were in range
@@ -41,7 +36,13 @@
 
 -- Repr -----------------------------------------------------------------------
 -- | Read elements from a partitioned array.
-instance (Repr r1 e, Repr r2 e) => Repr (P r1 r2) e where
+instance (Source r1 e, Source r2 e) => Source (P r1 r2) e where
+ data Array (P r1 r2) sh e
+        = APart !sh                          -- size of the whole array
+                !(Range sh) !(Array r1 sh e) -- if in range use this array
+                !(Array r2 sh e)             -- otherwise use this array
+
+
  index (APart _ range arr1 arr2) ix
    | inRange range ix   = index arr1 ix
    | otherwise          = index arr2 ix
@@ -66,16 +67,18 @@
 {-# INLINE deepSeqRange #-}
 
 
--- Fill -----------------------------------------------------------------------
-instance ( FillRange r1 r3 sh e, Fill r2 r3 sh e
-         , Fillable r3 e)
-        => Fill (P r1 r2) r3 sh e where
- fillP (APart _ (Range ix sz _) arr1 arr2) marr
-  = do  fillRangeP arr1 marr ix sz
-        fillP arr2 marr
- {-# INLINE fillP #-}
+-- Load -----------------------------------------------------------------------
+instance (LoadRange r1 sh e, Load r2 sh e)
+        => Load (P r1 r2) sh e where
+ loadP (APart _ (Range ix sz _) arr1 arr2) marr
+  = do  loadRangeP arr1 marr ix sz
+        loadP arr2 marr
+ {-# INLINE loadP #-}
 
- fillS (APart _ (Range ix sz _) arr1 arr2) marr
-  = do  fillRangeS arr1 marr ix sz
-        fillS arr2 marr
- {-# INLINE fillS #-}
+ loadS (APart _ (Range ix sz _) arr1 arr2) marr
+  = do  loadRangeS arr1 marr ix sz
+        loadS arr2 marr
+ {-# INLINE loadS #-}
+
+
+
diff --git a/Data/Array/Repa/Repr/Unboxed.hs b/Data/Array/Repa/Repr/Unboxed.hs
--- a/Data/Array/Repa/Repr/Unboxed.hs
+++ b/Data/Array/Repa/Repr/Unboxed.hs
@@ -26,19 +26,12 @@
 --   This is the most efficient representation for numerical data.
 --
 data U
-data instance U.Unbox e => Array U sh e
-        = AUnboxed !sh !(U.Vector e)
-        
-deriving instance (Show sh, Show e, U.Unbox e)
-        => Show (Array U sh e)
 
-deriving instance (Read sh, Read e, U.Unbox e)
-        => Read (Array U sh e)
-
-
--- Repr -----------------------------------------------------------------------
 -- | Read elements from an unboxed vector array.
-instance U.Unbox a => Repr U a where
+instance U.Unbox a => Source U a where
+ data Array U sh a
+        = AUnboxed !sh !(U.Vector a)
+
  linearIndex (AUnboxed _ vec) ix
         = vec U.! ix
  {-# INLINE linearIndex #-}
@@ -56,32 +49,39 @@
  {-# INLINE deepSeqArray #-}
 
 
+deriving instance (Show sh, Show e, U.Unbox e)
+        => Show (Array U sh e)
+
+deriving instance (Read sh, Read e, U.Unbox e)
+        => Read (Array U sh e)
+
+
 -- Fill -----------------------------------------------------------------------
 -- | Filling of unboxed vector arrays.
-instance U.Unbox e => Fillable U e where
- data MArr U e 
-  = UMArr (UM.IOVector e)
+instance U.Unbox e => Target U e where
+ data MVec U e 
+  = UMVec (UM.IOVector e)
 
- newMArr n
-  = liftM UMArr (UM.new n)
- {-# INLINE newMArr #-}
+ newMVec n
+  = liftM UMVec (UM.new n)
+ {-# INLINE newMVec #-}
 
- unsafeWriteMArr (UMArr v) ix
+ unsafeWriteMVec (UMVec v) ix
   = UM.unsafeWrite v ix
- {-# INLINE unsafeWriteMArr #-}
+ {-# INLINE unsafeWriteMVec #-}
 
- unsafeFreezeMArr sh (UMArr mvec)     
+ unsafeFreezeMVec sh (UMVec mvec)     
   = do  vec     <- U.unsafeFreeze mvec
         return  $  AUnboxed sh vec
- {-# INLINE unsafeFreezeMArr #-}
+ {-# INLINE unsafeFreezeMVec #-}
 
- deepSeqMArr (UMArr vec) x
+ deepSeqMVec (UMVec vec) x
   = vec `seq` x
- {-# INLINE deepSeqMArr #-}
+ {-# INLINE deepSeqMVec #-}
 
- touchMArr _ 
+ touchMVec _ 
   = return ()
- {-# INLINE touchMArr #-}
+ {-# INLINE touchMVec #-}
 
 
 -- Conversions ----------------------------------------------------------------
@@ -90,7 +90,8 @@
 --   * This is an alias for `computeS` with a more specific type.
 --
 computeUnboxedS
-        :: Fill r1 U sh e
+        :: ( Shape sh
+           , Load r1 sh e, U.Unbox e)
         => Array r1 sh e -> Array U sh e
 computeUnboxedS = computeS
 {-# INLINE computeUnboxedS #-}
@@ -101,7 +102,8 @@
 --   * This is an alias for `computeP` with a more specific type.
 --
 computeUnboxedP
-        :: (Fill r1 U sh e, Monad m, U.Unbox e)
+        :: ( Shape sh
+           , Load r1 sh e, Monad m, U.Unbox e)
         => Array r1 sh e -> m (Array U sh e)
 computeUnboxedP = computeP
 {-# INLINE computeUnboxedP #-}
diff --git a/Data/Array/Repa/Repr/Undefined.hs b/Data/Array/Repa/Repr/Undefined.hs
--- a/Data/Array/Repa/Repr/Undefined.hs
+++ b/Data/Array/Repa/Repr/Undefined.hs
@@ -4,7 +4,7 @@
 where
 import Data.Array.Repa.Base
 import Data.Array.Repa.Shape
-import Data.Array.Repa.Eval.Fill
+import Data.Array.Repa.Eval
 
 
 -- | An array with undefined elements.
@@ -12,19 +12,14 @@
 --   * This is normally used as the last representation in a partitioned array, 
 --     as the previous partitions are expected to provide full coverage.
 data X
-data instance Array X sh e
-        = AUndefined !sh
 
-deriving instance Show sh 
-        => Show (Array X sh e)
 
-deriving instance Read sh 
-        => Read (Array X sh e)
-
-
 -- | Undefined array elements. Inspecting them yields `error`.
 --
-instance Repr X e where
+instance Source X e where
+ data Array X sh e
+        = AUndefined !sh
+
  deepSeqArray _ x
         = x
  {-# INLINE deepSeqArray #-}
@@ -40,10 +35,17 @@
  linearIndex (AUndefined _) ix
         = error $ "Repa: array element at " ++ show ix ++ " is undefined."
  {-# INLINE linearIndex #-}
- 
 
-instance (Shape sh, Fillable r2 e, Num e) => Fill X r2 sh e where
- fillS _ _ = return ()
- fillP _ _ = return ()
+
+deriving instance Show sh 
+        => Show (Array X sh e)
+
+deriving instance Read sh 
+        => Read (Array X sh e)
+
+
+instance (Shape sh, Num e) => Load X sh e where
+ loadS _ _ = return ()
+ loadP _ _ = return ()
 
 
diff --git a/Data/Array/Repa/Repr/Vector.hs b/Data/Array/Repa/Repr/Vector.hs
--- a/Data/Array/Repa/Repr/Vector.hs
+++ b/Data/Array/Repa/Repr/Vector.hs
@@ -19,19 +19,12 @@
 --   have an `Unbox` instsance. If it does, then use the Unboxed `U`
 --   representation will be faster.
 data V
-data instance Array V sh e
-        = AVector !sh !(V.Vector e)
         
-deriving instance (Show sh, Show e)
-        => Show (Array V sh e)
-
-deriving instance (Read sh, Read e)
-        => Read (Array V sh e)
-
-
--- Repr -----------------------------------------------------------------------
 -- | Read elements from a boxed vector array.
-instance Repr V a where
+instance Source V a where
+ data Array V sh a
+        = AVector !sh !(V.Vector a)
+
  linearIndex (AVector _ vec) ix
         = vec V.! ix
  {-# INLINE linearIndex #-}
@@ -49,32 +42,39 @@
  {-# INLINE deepSeqArray #-}
 
 
+deriving instance (Show sh, Show e)
+        => Show (Array V sh e)
+
+deriving instance (Read sh, Read e)
+        => Read (Array V sh e)
+
+
 -- Fill -----------------------------------------------------------------------
 -- | Filling of boxed vector arrays.
-instance Fillable V e where
- data MArr V e 
-  = MVec (VM.IOVector e)
+instance Target V e where
+ data MVec V e 
+  = MVector (VM.IOVector e)
 
- newMArr n
-  = liftM MVec (VM.new n)
- {-# INLINE newMArr #-}
+ newMVec n
+  = liftM MVector (VM.new n)
+ {-# INLINE newMVec #-}
 
- unsafeWriteMArr (MVec v) ix
+ unsafeWriteMVec (MVector v) ix
   = VM.unsafeWrite v ix
- {-# INLINE unsafeWriteMArr #-}
+ {-# INLINE unsafeWriteMVec #-}
 
- unsafeFreezeMArr sh (MVec mvec)     
+ unsafeFreezeMVec sh (MVector mvec)     
   = do  vec     <- V.unsafeFreeze mvec
         return  $  AVector sh vec
- {-# INLINE unsafeFreezeMArr #-}
+ {-# INLINE unsafeFreezeMVec #-}
 
- deepSeqMArr !_vec x
+ deepSeqMVec !_vec x
   = x
- {-# INLINE deepSeqMArr #-}
+ {-# INLINE deepSeqMVec #-}
 
- touchMArr _ 
+ touchMVec _ 
   = return ()
- {-# INLINE touchMArr #-}
+ {-# INLINE touchMVec #-}
 
 
 -- Conversions ----------------------------------------------------------------
@@ -83,7 +83,7 @@
 --   * This is an alias for `compute` with a more specific type.
 --
 computeVectorS
-        :: Fill r1 V sh e
+        :: (Shape sh, Load r1 sh e)
         => Array r1 sh e -> Array V sh e
 computeVectorS   = computeS
 {-# INLINE computeVectorS #-}
@@ -91,7 +91,7 @@
 
 -- | Parallel computation of array elements.
 computeVectorP
-        :: (Fill r1 V sh e, Monad m)
+        :: (Shape sh, Load r1 sh e, Monad m)
         => Array r1 sh e -> m (Array V sh e)
 computeVectorP   = computeP
 {-# INLINE computeVectorP #-}
diff --git a/Data/Array/Repa/Specialised/Dim2.hs b/Data/Array/Repa/Specialised/Dim2.hs
--- a/Data/Array/Repa/Specialised/Dim2.hs
+++ b/Data/Array/Repa/Specialised/Dim2.hs
@@ -73,7 +73,7 @@
 --   The border must be the same width on all sides.
 --
 makeBordered2
-	:: (Repr r1 a, Repr r2 a)
+	:: (Source r1 a, Source r2 a)
         => DIM2			-- ^ Extent of array.
 	-> Int			-- ^ Width of border.
 	-> Array r1 DIM2 a	-- ^ Array for internal elements.
diff --git a/Data/Array/Repa/Stencil/Base.hs b/Data/Array/Repa/Stencil/Base.hs
--- a/Data/Array/Repa/Stencil/Base.hs
+++ b/Data/Array/Repa/Stencil/Base.hs
@@ -9,8 +9,11 @@
 
 -- | How to handle the case when the stencil lies partly outside the array.
 data Boundary a
-	-- | Treat points outside as having a constant value.
-	= BoundConst a
+        -- | Use a fixed value for border regions.
+        = BoundFixed a
+
+	-- | Treat points outside the array as having a constant value.
+	| BoundConst a
 
 	-- | Clamp points outside to the same value as the edge pixel.
 	| BoundClamp
diff --git a/Data/Array/Repa/Stencil/Dim2.hs b/Data/Array/Repa/Stencil/Dim2.hs
--- a/Data/Array/Repa/Stencil/Dim2.hs
+++ b/Data/Array/Repa/Stencil/Dim2.hs
@@ -11,11 +11,10 @@
 --   fits in the 7x7 tile.
 --
 module Data.Array.Repa.Stencil.Dim2
-	( 
-	-- * Stencil creation
+	( -- * Stencil creation
 	  makeStencil2, stencil2
 
-	-- * Stencil operators
+	  -- * Stencil operators
 	, PC5, mapStencil2, forStencil2)
 where
 import Data.Array.Repa.Base
@@ -42,10 +41,10 @@
 -- Wrappers -------------------------------------------------------------------
 -- | Like `mapStencil2` but with the parameters flipped.
 forStencil2
-        :: Repr r a
+        :: Source r a
         => Boundary a
-	-> Array r DIM2 a
-	-> Stencil DIM2 a
+	-> Array  r DIM2 a
+	-> Stencil  DIM2 a
 	-> Array PC5 DIM2 a
 
 {-# INLINE forStencil2 #-}
@@ -56,7 +55,7 @@
 -------------------------------------------------------------------------------
 -- | Apply a stencil to every element of a 2D array.
 mapStencil2
-        :: Repr r a
+        :: Source r a
         => Boundary a		-- ^ How to handle the boundary of the array.
 	-> Stencil DIM2 a	-- ^ Stencil to apply.
 	-> Array r DIM2 a		-- ^ Array to apply stencil to.
@@ -113,9 +112,9 @@
         {-# INLINE getBorder' #-}
         getBorder' ix
          = case boundary of
-                BoundConst c    -> c
-                BoundClamp      -> unsafeAppStencilCursor2_clamp addDim stencil
-                                        arr ix
+                BoundFixed c    -> c
+                BoundConst c    -> unsafeAppStencilCursor2_const addDim stencil c arr ix
+                BoundClamp      -> unsafeAppStencilCursor2_clamp addDim stencil arr ix
 
    in
     --  internal region
@@ -130,7 +129,7 @@
 
 
 unsafeAppStencilCursor2
-	:: Repr r a
+	:: Source r a
 	=> (DIM2 -> Cursor -> Cursor)
 	-> Stencil DIM2 a
 	-> Array r DIM2 a
@@ -163,10 +162,59 @@
                 , " It must fit within a 7x7 tile to be compiled statically." ]
 
 
+-- | Like above, but treat elements outside the array has having a constant value.
+unsafeAppStencilCursor2_const
+        :: forall r a
+        .  Source r a
+        => (DIM2 -> DIM2 -> DIM2)
+        -> Stencil DIM2 a
+        -> a
+        -> Array r DIM2 a
+        -> DIM2
+        -> a
+
+{-# INLINE unsafeAppStencilCursor2_const #-}
+unsafeAppStencilCursor2_const shift
+           (StencilStatic sExtent zero loads)
+           fixed arr cur
+
+        | _ :. sHeight      :. sWidth       <- sExtent
+        , _ :. (I# aHeight) :. (I# aWidth)  <- extent arr
+        , sHeight <= 7, sWidth <= 7
+        = let
+                -- Get data from the manifest array.
+                {-# INLINE getData #-}
+                getData :: DIM2 -> a
+                getData (Z :. (I# y) :. (I# x))
+                 = getData' x y
+
+                {-# NOINLINE getData' #-}
+                getData' :: Int# -> Int# -> a
+                getData' !x !y
+                 | x <# 0#       = fixed
+                 | x >=# aWidth  = fixed
+                 | y <# 0#       = fixed
+                 | y >=# aHeight = fixed
+                 | otherwise     = arr `unsafeIndex` (Z :. (I# y) :.  (I# x))
+
+                -- Build a function to pass data from the array to our stencil.
+                {-# INLINE oload #-}
+                oload oy ox
+                 = let  !cur' = shift (Z :. oy :. ox) cur
+                   in   loads (Z :. oy :. ox) (getData cur')
+
+           in   template7x7 oload zero
+
+        | otherwise
+        = error $ unlines 
+                [ "mapStencil2: Your stencil is too big for this method."
+                , " It must fit within a 7x7 tile to be compiled statically." ]
+
+
 -- | Like above, but clamp out of bounds array values to the closest real value.
 unsafeAppStencilCursor2_clamp
 	:: forall r a
-	.  Repr r a
+	.  Source r a
 	=> (DIM2 -> DIM2 -> DIM2)
 	-> Stencil DIM2 a
 	-> Array r DIM2 a
diff --git a/repa.cabal b/repa.cabal
--- a/repa.cabal
+++ b/repa.cabal
@@ -1,5 +1,5 @@
 Name:                repa
-Version:             3.1.4.2
+Version:             3.2.1.1
 License:             BSD3
 License-file:        LICENSE
 Author:              The DPH Team
@@ -82,7 +82,8 @@
         Data.Array.Repa.Eval.Cursored
         Data.Array.Repa.Eval.Interleaved
         Data.Array.Repa.Eval.Elt
-        Data.Array.Repa.Eval.Fill
+        Data.Array.Repa.Eval.Target
+        Data.Array.Repa.Eval.Load
         Data.Array.Repa.Eval.Reduction
         Data.Array.Repa.Eval.Selection
         Data.Array.Repa.Stencil.Base
