diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,20 @@
 Changelog
 =========
 
+Version 0.2.6.0
+---------------
+
+*August 6, 2018*
+
+<https://github.com/mstksg/backprop/releases/tag/v0.2.6.0>
+
+*   Dropped `Expr` instance of `Backprop`. I don't think anyone was actually
+    using this.  If you need this, please use `Numeric.Backprop.Num` instead!
+*   Removed *Rec* re-exports.
+*   Compatibility with *vinyl-0.9*, using the *Data.Vinyl.Recursive* interface.
+    This requires some minor reshuffling of constraints but should not affect
+    any monomorphic usage.
+
 Version 0.2.5.0
 ---------------
 
diff --git a/backprop.cabal b/backprop.cabal
--- a/backprop.cabal
+++ b/backprop.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 3b204e36b38185be2d92ef4a0e6c3d9ad3cc90fbbf5cf0ccfc4b936a65fb7cac
+-- hash: 5fe92f47f037a2d14b0df727ed7cb1213b58e39938cf6b691b376d5caa565d5d
 
 name:           backprop
-version:        0.2.5.0
+version:        0.2.6.0
 synopsis:       Heterogeneous automatic differentation
 description:    Write your functions to compute your result, and the library will
                 automatically generate functions to compute your gradient.
@@ -61,10 +61,9 @@
     , microlens
     , primitive
     , reflection
-    , simple-reflect
     , transformers
     , vector
-    , vinyl >=0.6
+    , vinyl >=0.9
   exposed-modules:
       Numeric.Backprop
       Numeric.Backprop.Class
diff --git a/src/Data/Type/Util.hs b/src/Data/Type/Util.hs
--- a/src/Data/Type/Util.hs
+++ b/src/Data/Type/Util.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DataKinds              #-}
+{-# LANGUAGE FlexibleContexts       #-}
 {-# LANGUAGE GADTs                  #-}
 {-# LANGUAGE LambdaCase             #-}
 {-# LANGUAGE PatternSynonyms        #-}
@@ -150,7 +151,7 @@
 {-# INLINE zipVecList #-}
 
 splitRec
-    :: forall f as bs. (RecApplicative as)
+    :: forall f as bs. RecApplicative as
     => Rec f (as ++ bs)
     -> (Rec f as, Rec f bs)
 splitRec = go (rpure Proxy)
diff --git a/src/Numeric/Backprop.hs b/src/Numeric/Backprop.hs
--- a/src/Numeric/Backprop.hs
+++ b/src/Numeric/Backprop.hs
@@ -108,14 +108,13 @@
     -- *** No gradients
   , noGrad1, noGrad
     -- * Utility
-  , Rec(..), Reifies
+  , Reifies
   ) where
 
 import           Data.Functor.Identity
 import           Data.Maybe
 import           Data.Reflection
 import           Data.Vinyl
-import           Data.Vinyl.TypeLevel
 import           GHC.Generics
 import           Lens.Micro
 import           Numeric.Backprop.Class
@@ -179,16 +178,16 @@
 -- of @'BVar' s 'Double'@, @'BVar' s 'Float'@, and @'BVar' s 'Double'@, and
 -- can be pattern matched on using ':<' (cons) and 'Ø' (nil).
 --
--- The @'AllConstrained' 'Backprop' as@ in the constraint says that every
+-- The @'RPureConstrained' 'Backprop' as@ in the constraint says that every
 -- value in the type-level list @as@ must have a 'Backprop' instance.  This
 -- means you can use, say, @'[Double, Float, Int]@, but not @'[Double,
 -- Bool, String]@.
 --
 -- If you stick to /concerete/, monomorphic usage of this (with specific
 -- types, typed into source code, known at compile-time), then
--- @'AllConstrained' 'Backprop' as@ should be fulfilled automatically.
+-- @'RPureConstrained' 'Backprop' as@ should be fulfilled automatically.
 backpropN
-    :: (AllConstrained Backprop as, RecApplicative as, Backprop b)
+    :: (RPureConstrained Backprop as, Backprop b)
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Rec Identity as
     -> (b, Rec Identity as)
@@ -203,7 +202,7 @@
 --
 -- @since 0.2.0.0
 backpropWithN
-    :: (AllConstrained Backprop as, RecApplicative as)
+    :: RPureConstrained Backprop as
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Rec Identity as
     -> (b, b -> Rec Identity as)
@@ -275,7 +274,7 @@
 -- | 'gradBP' generalized to multiple inputs of different types.  See
 -- documentation for 'backpropN' for more details.
 gradBPN
-    :: (AllConstrained Backprop as, RecApplicative as, Backprop b)
+    :: (RPureConstrained Backprop as, Backprop b)
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Rec Identity as
     -> Rec Identity as
@@ -334,7 +333,7 @@
 -- 'bpOp' . 'liftOp' = 'id'
 -- @
 bpOp
-    :: (AllConstrained Backprop as, RecApplicative as)
+    :: RPureConstrained Backprop as
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Op as b
 bpOp = E.bpOp E.zeroFuncs
@@ -670,7 +669,7 @@
 -- information, and "Numeric.Backprop.Op#prod" for a mini-tutorial on using
 -- 'Rec'.
 liftOp
-    :: (AllConstrained Backprop as, RecApplicative as, Reifies s W)
+    :: (RPureConstrained Backprop as, Reifies s W)
     => Op as b
     -> Rec (BVar s) as
     -> BVar s b
@@ -789,7 +788,7 @@
 --
 -- @since 0.1.4.0
 isoVarN
-    :: (AllConstrained Backprop as, RecApplicative as, Reifies s W)
+    :: (RPureConstrained Backprop as, Reifies s W)
     => (Rec Identity as -> b)
     -> (b -> Rec Identity as)
     -> Rec (BVar s) as
@@ -960,8 +959,7 @@
        , E.BVGroup s as (Rep (z f)) (Rep (z (BVar s)))
        , Backprop (z f)
        , Backprop (Rep (z f) ())
-       , AllConstrained Backprop as
-       , RecApplicative as
+       , RPureConstrained Backprop as
        , Reifies s W
        )
     => BVar s (z f)             -- ^ 'BVar' of value
@@ -995,8 +993,7 @@
        , E.BVGroup s as (Rep (z f)) (Rep (z (BVar s)))
        , Backprop (z f)
        , Backprop (Rep (z f) ())
-       , AllConstrained Backprop as
-       , RecApplicative as
+       , RPureConstrained Backprop as
        , Reifies s W
        )
     => z (BVar s)           -- ^ 'BVar's of fields
@@ -1014,7 +1011,7 @@
        , E.BVGroup s as (Rep (z f)) (Rep (z (BVar s)))
        , Backprop (Rep (z f) ())
        , Backprop (z f)
-       , AllConstrained Backprop as
+       , RPureConstrained Backprop as
        , RecApplicative as
        , Reifies s W
        )
diff --git a/src/Numeric/Backprop/Class.hs b/src/Numeric/Backprop/Class.hs
--- a/src/Numeric/Backprop/Class.hs
+++ b/src/Numeric/Backprop/Class.hs
@@ -61,7 +61,6 @@
 import           Data.Ratio
 import           Data.Void
 import           Data.Word
-import           Debug.SimpleReflect.Expr
 import           GHC.Exts
 import           GHC.Generics
 import           Numeric.Natural
@@ -1093,13 +1092,4 @@
     add (Arr.Kleisli f) (Arr.Kleisli g) = Arr.Kleisli $ \x ->
         add <$> f x <*> g x
     one (Arr.Kleisli f) = Arr.Kleisli ((fmap . fmap) one f)
-    {-# INLINE one #-}
-
--- | @since 0.2.4.0
-instance Backprop Expr where
-    zero = zeroNum
-    {-# INLINE zero #-}
-    add  = addNum
-    {-# INLINE add #-}
-    one  = oneNum
     {-# INLINE one #-}
diff --git a/src/Numeric/Backprop/Explicit.hs b/src/Numeric/Backprop/Explicit.hs
--- a/src/Numeric/Backprop/Explicit.hs
+++ b/src/Numeric/Backprop/Explicit.hs
@@ -54,7 +54,7 @@
     -- ** Multiple inputs
   , evalBP0
   , backprop2, evalBP2, gradBP2, backpropWith2
-  , backpropN, evalBPN, gradBPN, backpropWithN, RecApplicative, AllConstrained
+  , backpropN, evalBPN, gradBPN, backpropWithN, RPureConstrained
     -- * Manipulating 'BVar'
   , constVar, auto, coerceVar
   , viewVar, setVar, overVar
@@ -81,12 +81,11 @@
     -- *** No gradients
   , noGrad1, noGrad
     -- * Utility
-  , Rec(..), Reifies
+  , Reifies
   ) where
 
 import           Data.Bifunctor
 import           Data.Functor.Identity
-import           Data.Proxy
 import           Data.Reflection
 import           Data.Type.Util
 import           Data.Vinyl.Core
@@ -102,8 +101,8 @@
 -- 'Num' instances
 --
 -- @since 0.2.0.0
-zfNums :: (RecApplicative as, AllConstrained Num as) => Rec ZeroFunc as
-zfNums = rpureConstrained (Proxy @Num) zfNum
+zfNums :: RPureConstrained Num as => Rec ZeroFunc as
+zfNums = rpureConstrained @Num zfNum
 
 -- | 'zeroFunc' for instances of 'Functor'
 --
@@ -116,15 +115,15 @@
 -- 'Num' instances
 --
 -- @since 0.2.0.0
-afNums :: (RecApplicative as, AllConstrained Num as) => Rec AddFunc as
-afNums = rpureConstrained (Proxy @Num) afNum
+afNums :: RPureConstrained Num as => Rec AddFunc as
+afNums = rpureConstrained @Num afNum
 
 -- | 'ZeroFunc's for every item in a type level list based on their
 -- 'Num' instances
 --
 -- @since 0.2.0.0
-ofNums :: (RecApplicative as, AllConstrained Num as) => Rec OneFunc as
-ofNums = rpureConstrained (Proxy @Num) ofNum
+ofNums :: RPureConstrained Num as => Rec OneFunc as
+ofNums = rpureConstrained @Num ofNum
 
 -- | 'OneFunc' for instances of 'Functor'
 --
@@ -137,22 +136,22 @@
 -- type has an instance of 'Backprop'.
 --
 -- @since 0.2.0.0
-zeroFuncs :: (RecApplicative as, AllConstrained Backprop as) => Rec ZeroFunc as
-zeroFuncs = rpureConstrained (Proxy @Backprop) zeroFunc
+zeroFuncs :: RPureConstrained Backprop as => Rec ZeroFunc as
+zeroFuncs = rpureConstrained @Backprop zeroFunc
 
 -- | Generate an 'AddFunc' for every type in a type-level list, if every
 -- type has an instance of 'Backprop'.
 --
 -- @since 0.2.0.0
-addFuncs :: (RecApplicative as, AllConstrained Backprop as) => Rec AddFunc as
-addFuncs = rpureConstrained (Proxy @Backprop) addFunc
+addFuncs :: RPureConstrained Backprop as => Rec AddFunc as
+addFuncs = rpureConstrained @Backprop addFunc
 
 -- | Generate an 'OneFunc' for every type in a type-level list, if every
 -- type has an instance of 'Backprop'.
 --
 -- @since 0.2.0.0
-oneFuncs :: (RecApplicative as, AllConstrained Backprop as) => Rec OneFunc as
-oneFuncs = rpureConstrained (Proxy @Backprop) oneFunc
+oneFuncs :: RPureConstrained Backprop as => Rec OneFunc as
+oneFuncs = rpureConstrained @Backprop oneFunc
 
 -- | Shorter alias for 'constVar', inspired by the /ad/ library.
 --
diff --git a/src/Numeric/Backprop/Internal.hs b/src/Numeric/Backprop/Internal.hs
--- a/src/Numeric/Backprop/Internal.hs
+++ b/src/Numeric/Backprop/Internal.hs
@@ -74,6 +74,7 @@
 import           Unsafe.Coerce
 import qualified Data.Vector               as V
 import qualified Data.Vector.Mutable       as MV
+import qualified Data.Vinyl.Recursive      as VR
 
 -- | "Zero out" all components of a value.  For scalar values, this should
 -- just be @'const' 0@.  For vectors and matrices, this should set all
@@ -233,7 +234,7 @@
        -> TapeNode a
 
 forceTapeNode :: TapeNode a -> ()
-forceTapeNode (TN inps !_) = rfoldMap forceInpRef inps `seq` ()
+forceTapeNode (TN inps !_) = VR.rfoldMap forceInpRef inps `seq` ()
 {-# INLINE forceTapeNode #-}
 
 data SomeTapeNode :: Type where
@@ -243,7 +244,7 @@
 
 -- | Debugging string for a 'SomeTapeMode'.
 debugSTN :: SomeTapeNode -> String
-debugSTN (STN TN{..}) = show . rfoldMap ((:[]) . debugIR) $ _tnInputs
+debugSTN (STN TN{..}) = show . VR.rfoldMap ((:[]) . debugIR) $ _tnInputs
 
 -- | An ephemeral Wengert Tape in the environment.  Used internally to
 -- track of the computational graph of variables.
@@ -285,8 +286,8 @@
     Just xs -> return $ constVar (evalOp o xs)
     Nothing -> insertNode tn y (reflect (Proxy @s))
   where
-    (y,g) = runOpWith o (rmap (Identity . _bvVal) vs)
-    tn = TN { _tnInputs = rzipWith go afs vs
+    (y,g) = runOpWith o (VR.rmap (Identity . _bvVal) vs)
+    tn = TN { _tnInputs = VR.rzipWith go afs vs
             , _tnGrad   = g
             }
     go :: forall a. AddFunc a -> BVar s a -> InpRef a
@@ -650,7 +651,7 @@
         delts <- toList <$> V.freeze (_rInputs r)
         return . fromMaybe (internalError "backpropN") $
           fillRec (\z -> maybe z (Identity . unsafeCoerce))
-            (rzipWith (fmap . runZF) zfs xs)
+            (VR.rzipWith (fmap . runZF) zfs xs)
             delts
       where
         go :: forall a. Identity a -> ((Sum Int, Endo [Maybe Any]),())
diff --git a/src/Numeric/Backprop/Num.hs b/src/Numeric/Backprop/Num.hs
--- a/src/Numeric/Backprop/Num.hs
+++ b/src/Numeric/Backprop/Num.hs
@@ -76,14 +76,13 @@
     -- *** No gradients
   , noGrad1, noGrad
     -- * Utility
-  , Rec(..), Reifies
+  , Reifies
   ) where
 
 import           Data.Functor.Identity
 import           Data.Maybe
 import           Data.Reflection
 import           Data.Vinyl
-import           Data.Vinyl.TypeLevel
 import           Lens.Micro
 import           Numeric.Backprop.Explicit (BVar, W)
 import           Numeric.Backprop.Op
@@ -92,16 +91,17 @@
 -- | 'Numeric.Backprop.backpropN', but with 'Num' constraints instead of
 -- 'Backprop' constraints.
 --
--- The @'AllConstrained' 'Num' as@ in the constraint says that every value in the
--- type-level list @as@ must have a 'Num' instance.  This means you can
--- use, say, @'[Double, Float, Int]@, but not @'[Double, Bool, String]@.
+-- The @'RPureConstrained' 'Num' as@ in the constraint says that every
+-- value in the type-level list @as@ must have a 'Num' instance.  This
+-- means you can use, say, @'[Double, Float, Int]@, but not @'[Double,
+-- Bool, String]@.
 --
 -- If you stick to /concerete/, monomorphic usage of this (with specific
--- types, typed into source code, known at compile-time), then @'AllConstrained'
--- 'Num' as@ should be fulfilled automatically.
+-- types, typed into source code, known at compile-time), then
+-- @'AllPureConstrained' 'Num' as@ should be fulfilled automatically.
 --
 backpropN
-    :: (AllConstrained Num as, RecApplicative as, Num b)
+    :: (RPureConstrained Num as, Num b)
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Rec Identity as
     -> (b, Rec Identity as)
@@ -117,7 +117,7 @@
 --
 -- @since 0.2.0.0
 backpropWithN
-    :: (AllConstrained Num as, RecApplicative as)
+    :: RPureConstrained Num as
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Rec Identity as
     -> (b, b -> Rec Identity as)
@@ -167,7 +167,7 @@
 -- | 'Numeric.Backprop.gradBPN', but with 'Num' constraints instead of
 -- 'Backprop' constraints.
 gradBPN
-    :: (AllConstrained Num as, RecApplicative as, Num b)
+    :: (RPureConstrained Num as, Num b)
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Rec Identity as
     -> Rec Identity as
@@ -214,7 +214,7 @@
 -- | 'Numeric.Backprop.bpOp', but with 'Num' constraints instead of
 -- 'Backprop' constraints.
 bpOp
-    :: (AllConstrained Num as, RecApplicative as)
+    :: RPureConstrained Num as
     => (forall s. Reifies s W => Rec (BVar s) as -> BVar s b)
     -> Op as b
 bpOp = E.bpOp E.zfNums
@@ -394,7 +394,7 @@
 -- | 'Numeric.Backprop.liftOp', but with 'Num' constraints instead of
 -- 'Backprop' constraints.
 liftOp
-    :: (AllConstrained Num as, RecApplicative as, Reifies s W)
+    :: (RPureConstrained Num as, Reifies s W)
     => Op as b
     -> Rec (BVar s) as
     -> BVar s b
@@ -473,7 +473,7 @@
 -- | 'Numeric.Backprop.isoVarN', but with 'Num' constraints instead of
 -- 'Backprop' constraints.
 isoVarN
-    :: (AllConstrained Num as, RecApplicative as, Reifies s W)
+    :: (RPureConstrained Num as, Reifies s W)
     => (Rec Identity as -> b)
     -> (b -> Rec Identity as)
     -> Rec (BVar s) as
diff --git a/src/Numeric/Backprop/Op.hs b/src/Numeric/Backprop/Op.hs
--- a/src/Numeric/Backprop/Op.hs
+++ b/src/Numeric/Backprop/Op.hs
@@ -82,12 +82,12 @@
 import           Data.Coerce
 import           Data.Functor.Identity
 import           Data.List
-import           Data.Proxy
 import           Data.Type.Util
 import           Data.Vinyl.Core
 import           Data.Vinyl.TypeLevel
 import           Lens.Micro
 import           Lens.Micro.Extras
+import qualified Data.Vinyl.Recursive  as VR
 
 -- $opdoc
 -- 'Op's contain information on a function as well as its gradient, but
@@ -205,7 +205,7 @@
 -- can compose them with an @'Op' '[b1,b2,b3] c@ to create an @'Op' as
 -- c@.
 composeOp
-    :: forall as bs c. (AllConstrained Num as, RecApplicative as)
+    :: forall as bs c. (RPureConstrained Num as)
     => Rec (Op as) bs   -- ^ 'Rec' of 'Op's taking @as@ and returning
                          --     different @b@ in @bs@
     -> Op bs c           -- ^ 'OpM' taking eac of the @bs@ from the
@@ -217,15 +217,15 @@
         gFunc g0 =
           let g1 = gFz g0
               g2s :: Rec (Const (Rec Identity as)) bs
-              g2s = rzipWith (\oc (Identity g) -> Const $ runOpCont oc g)
+              g2s = VR.rzipWith (\oc (Identity g) -> Const $ runOpCont oc g)
                         conts g1
-          in  rmap (\(Dict x) -> Identity x)
-                . foldl' (rzipWith (\(Dict !x) (Identity y) ->
-                                        let q = x + y in q `seq` Dict q
-                                   )
+          in  VR.rmap (\(Dict x) -> Identity x)
+                . foldl' (VR.rzipWith (\(Dict !x) (Identity y) ->
+                                         let q = x + y in q `seq` Dict q
+                                    )
                          )
-                    (rpureConstrained (Proxy @Num) (Dict @Num 0))
-                . rfoldMap ((:[]) . getConst)
+                    (rpureConstrained @Num (Dict @Num 0))
+                . VR.rfoldMap ((:[]) . getConst)
                 $ g2s
     in (z, gFunc)
 
@@ -233,7 +233,7 @@
 -- function only takes one input, so the two 'Op's can be directly piped
 -- together, like for '.'.
 composeOp1
-    :: (AllConstrained Num as, RecApplicative as)
+    :: RPureConstrained Num as
     => Op as b
     -> Op '[b] c
     -> Op as c
@@ -250,7 +250,7 @@
 -- @
 infixr 9 ~.
 (~.)
-    :: (AllConstrained Num as, RecApplicative as)
+    :: (RPureConstrained Num as)
     => Op '[b] c
     -> Op as b
     -> Op as c
@@ -419,11 +419,11 @@
 -- >>> gradOp' (opConst 10) (1 :& 2 :& 3 :& RNil)
 -- (10, 0 :& 0 :& 0 :& RNil)
 opConst
-    :: forall as a. (AllConstrained Num as, RecApplicative as)
+    :: forall as a. RPureConstrained Num as
     => a
     -> Op as a
 opConst x = Op $ const
-    (x , const $ rpureConstrained (Proxy @Num) 0)
+    (x , const $ rpureConstrained @Num 0)
 {-# INLINE opConst #-}
 
 -- | Create an 'Op' that takes no inputs and always returns the given
@@ -543,7 +543,7 @@
       in  (q, (\(!dx, !dy, !dz) -> Identity dx :& Identity dy :& Identity dz :& RNil) . dxdydz)
 {-# INLINE op3 #-}
 
-instance (RecApplicative as, AllConstrained Num as, Num a) => Num (Op as a) where
+instance (RPureConstrained Num as, Num a) => Num (Op as a) where
     o1 + o2       = composeOp (o1 :& o2 :& RNil) (+.)
     {-# INLINE (+) #-}
     o1 - o2       = composeOp (o1 :& o2 :& RNil) (-.)
@@ -559,14 +559,14 @@
     fromInteger x = opConst (fromInteger x)
     {-# INLINE fromInteger #-}
 
-instance (RecApplicative as, AllConstrained Num as, Fractional a) => Fractional (Op as a) where
+instance (RPureConstrained Num as, Fractional a) => Fractional (Op as a) where
     o1 / o2        = composeOp (o1 :& o2 :& RNil) (/.)
     recip o        = composeOp (o  :& RNil)       recipOp
     {-# INLINE recip #-}
     fromRational x = opConst (fromRational x)
     {-# INLINE fromRational #-}
 
-instance (RecApplicative as, AllConstrained Floating as, AllConstrained Fractional as, AllConstrained Num as, Floating a) => Floating (Op as a) where
+instance (RecApplicative as, AllConstrained Floating as, AllConstrained Fractional as, AllConstrained Num as, RPureConstrained Num as, Floating a) => Floating (Op as a) where
     pi            = opConst pi
     {-# INLINE pi #-}
     exp   o       = composeOp (o  :& RNil)       expOp
