diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,7 @@
+1.1.2
+-----
+* Dependency bump for `reflection` compatibility
+
 1.1.1
 -----
 * Fixed an infinite loop in the default definition of `liftI2`.
diff --git a/linear.cabal b/linear.cabal
--- a/linear.cabal
+++ b/linear.cabal
@@ -1,6 +1,6 @@
 name:          linear
 category:      Math, Algebra
-version:       1.1.1
+version:       1.1.2
 license:       BSD3
 cabal-version: >= 1.8
 license-file:  LICENSE
@@ -35,7 +35,7 @@
     distributive         >= 0.2.2 && < 1,
     ghc-prim,
     hashable             >= 1.1   && < 1.3,
-    reflection           >= 1.1.6 && < 2,
+    reflection           >= 1.3.2 && < 2,
     semigroups           >= 0.9   && < 1,
     semigroupoids        >= 3     && < 4,
     tagged               >= 0.4.4 && < 1,
@@ -46,6 +46,7 @@
 
   exposed-modules:
     Linear
+    Linear.Affine
     Linear.Conjugate
     Linear.Core
     Linear.Epsilon
diff --git a/src/Linear/Affine.hs b/src/Linear/Affine.hs
new file mode 100644
--- /dev/null
+++ b/src/Linear/Affine.hs
@@ -0,0 +1,112 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE TypeFamilies #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Linear.Vector
+-- License     :  BSD-style (see the file LICENSE)
+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Operations on affine spaces.
+-----------------------------------------------------------------------------
+module Linear.Affine where
+
+import Control.Applicative
+import Data.Complex (Complex)
+import Data.Foldable as Foldable
+import Data.Functor.Bind
+import Data.Functor.Identity (Identity)
+import Data.HashMap.Lazy (HashMap)
+import Data.Hashable
+import Data.IntMap (IntMap)
+import Data.Ix
+import Data.Map (Map)
+import Data.Traversable as Traversable
+import Data.Vector (Vector)
+import Foreign.Storable
+import Linear.Core
+import Linear.Epsilon
+import Linear.Metric
+import Linear.Plucker
+import Linear.Quaternion
+import Linear.V
+import Linear.V0
+import Linear.V2
+import Linear.V3
+import Linear.V4
+import Linear.Vector
+
+-- | An affine space is roughly a vector space in which we have
+-- forgotten or at least pretend to have forgotten the origin.
+--
+-- > a .+^ (b .-. a)  =  b@
+-- > (a .+^ u) .+^ v  =  a .+^ (u ^+^ v)@
+-- > (a .-. b) ^+^ v  =  (a .+^ v) .-. q@
+class Additive (Diff p) => Affine p where
+  type Diff p :: * -> *
+  
+  infixl 6 .-.
+  -- | Get the difference between two points as a vector offset.
+  (.-.) :: Num a => p a -> p a -> Diff p a
+  
+  infixl 6 .+^
+  -- | Add a vector offset to a point.
+  (.+^) :: Num a => p a -> Diff p a -> p a
+
+  infixl 6 .-^
+  -- | Subtract a vector offset from a point.
+  (.-^) :: Num a => p a -> Diff p a -> p a
+  p .-^ v = p .+^ negated v
+  {-# INLINE (.-^) #-}
+
+-- | Compute the quadrance of the difference (the square of the distance)
+qdA :: (Affine p, Foldable (Diff p), Num a) => p a -> p a -> a
+qdA a b = Foldable.sum (fmap (join (*)) (a .-. b))
+
+-- | Distance between two points in an affine space
+distanceA :: (Floating a, Foldable (Diff p), Affine p) => p a -> p a -> a
+distanceA a b = sqrt (qdA a b)
+
+#define ADDITIVEC(CTX,T) instance CTX => Affine T where type Diff T = T ; \
+  (.-.) = (^-^) ; {-# INLINE (.-.) #-} ; (.+^) = (^+^) ; {-# INLINE (.+^) #-} ; \
+  (.-^) = (^-^) ; {-# INLINE (.-^) #-}
+#define ADDITIVE(T) ADDITIVEC((), T)
+
+ADDITIVE([])
+ADDITIVE(Complex)
+ADDITIVE(ZipList)
+ADDITIVE(Maybe)
+ADDITIVE(IntMap)
+ADDITIVE(Identity)
+ADDITIVE(Vector)
+ADDITIVE(V0)
+ADDITIVE(V2)
+ADDITIVE(V3)
+ADDITIVE(V4)
+ADDITIVE(Plucker)
+ADDITIVE(Quaternion)
+ADDITIVE(((->) b))
+ADDITIVEC(Ord k, (Map k))
+ADDITIVEC((Eq k, Hashable k), (HashMap k))
+ADDITIVEC(Dim n, (V n))
+
+-- | A handy wrapper to help distinguish points from vectors at the
+-- type level
+newtype Point f a = P (f a)
+  deriving ( Eq, Ord, Show, Read, Monad, Functor, Applicative, Foldable
+           , Traversable, Apply, Bind, Additive, Metric, Core, R2, R3, R4
+           , Fractional , Num, Ix, Storable, Epsilon
+           )
+
+instance Additive f => Affine (Point f) where
+  type Diff (Point f) = f
+  P x .-. P y = x ^-^ y
+  P x .+^ v = P (x ^+^ v)
+  P x .-^ v = P (x ^-^ v)
+
+-- | Vector spaces have origins.
+origin :: (Additive f, Num a) => Point f a
+origin = P zero
diff --git a/src/Linear/Conjugate.hs b/src/Linear/Conjugate.hs
--- a/src/Linear/Conjugate.hs
+++ b/src/Linear/Conjugate.hs
@@ -17,6 +17,7 @@
 import Data.Complex hiding (conjugate)
 import Data.Int
 import Data.Word
+import Foreign.C.Types (CFloat, CDouble)
 
 -- | An involutive ring
 class Num a => Conjugate a where
@@ -43,6 +44,8 @@
 instance Conjugate Word8
 instance Conjugate Double
 instance Conjugate Float
+instance Conjugate CFloat
+instance Conjugate CDouble
 instance (Conjugate a, RealFloat a) => Conjugate (Complex a) where
   {-# SPECIALIZE instance Conjugate (Complex Float) #-}
   {-# SPECIALIZE instance Conjugate (Complex Double) #-}
diff --git a/src/Linear/Epsilon.hs b/src/Linear/Epsilon.hs
--- a/src/Linear/Epsilon.hs
+++ b/src/Linear/Epsilon.hs
@@ -12,6 +12,7 @@
 module Linear.Epsilon
   ( Epsilon(..)
   ) where
+import Foreign.C.Types (CFloat, CDouble)
 
 -- | Provides a fairly subjective test to see if a quantity is near zero.
 --
@@ -36,4 +37,12 @@
 
 -- | @'abs' a '<=' 1e-12@
 instance Epsilon Double where
+  nearZero a = abs a <= 1e-12
+
+-- | @'abs' a '<=' 1e-6@
+instance Epsilon CFloat where
+  nearZero a = abs a <= 1e-6
+
+-- | @'abs' a '<=' 1e-12@
+instance Epsilon CDouble where
   nearZero a = abs a <= 1e-12
diff --git a/src/Linear/Metric.hs b/src/Linear/Metric.hs
--- a/src/Linear/Metric.hs
+++ b/src/Linear/Metric.hs
@@ -18,6 +18,7 @@
 
 import Data.Foldable as Foldable
 import Data.Functor.Identity
+import Data.Vector (Vector)
 import Linear.Epsilon
 import Linear.Vector
 
@@ -61,6 +62,8 @@
 
 instance Metric Identity where
   dot (Identity x) (Identity y) = x * y
+
+instance Metric Vector
 
 -- | Normalize a 'Metric' functor to have unit 'norm'. This function
 -- does not change the functor if its 'norm' is 0 or 1.
diff --git a/src/Linear/V.hs b/src/Linear/V.hs
--- a/src/Linear/V.hs
+++ b/src/Linear/V.hs
@@ -182,6 +182,7 @@
   | V.length v == reflectDim (Proxy :: Proxy n) = Just (V v)
   | otherwise                                   = Nothing
 
+#if !(MIN_VERSION_reflection(1,3,0))
 data Z  -- 0
 data D  (n :: *) -- 2n
 data SD (n :: *) -- 2n+1
@@ -226,5 +227,5 @@
   (q, 0) -> conT ''D  `appT` int q
   (q, 1) -> conT ''SD `appT` int q
   _     -> error "ghc is bad at math"
-
+#endif
 
diff --git a/src/Linear/Vector.hs b/src/Linear/Vector.hs
--- a/src/Linear/Vector.hs
+++ b/src/Linear/Vector.hs
@@ -23,6 +23,7 @@
   , basis
   , basisFor
   , kronecker
+  , outer
   ) where
 
 import Control.Applicative
@@ -301,3 +302,7 @@
   where aux i e = let i' = i + 1
                   in i' `seq` (i', setElement i e z)
         z = pure 0
+
+-- | Outer (tensor) product of two vectors
+outer :: (Functor f, Functor g, Num a) => f a -> g a -> f (g a)
+outer a b = fmap (\x->fmap (*x) b) a
