diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,24 @@
 Changelog
 =========
 
+Version 0.1.1.0
+---------------
+
+*Mar 25, 2018*
+
+<https://github.com/mstksg/hmatrix-backprop/releases/tag/v0.1.1.0>
+
+*   `dvmap`/`dmmap` family rewritten, which is a breaking API change.  Previous
+    version of `dvmap`/`dmmap` would not even compile at all if used, though,
+    because of nonsensical constraints, so it is likely that no code that
+    previously worked is now breaking.
+*   *backprop* types re-exported for convenience
+
+*Internal*
+
+*   Rewrote much code to use `isoVar` instead of `opIso`, for increased clarity
+    and cleanliness.  Requires *backprop-0.1.4.0*.
+
 Version 0.1.0.0
 ---------------
 
diff --git a/hmatrix-backprop.cabal b/hmatrix-backprop.cabal
--- a/hmatrix-backprop.cabal
+++ b/hmatrix-backprop.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 0d60d828b601d4eb24c4978c049e961589bc85fcabfd9c4c71ee0103caf1477e
+-- hash: 7bd7d72297fd6caf75a31bbc3856f764f21999255f99a4f6bcad71e4739acf2a
 
 name:           hmatrix-backprop
-version:        0.1.0.0
+version:        0.1.1.0
 synopsis:       hmatrix operations lifted for backprop
 description:    hmatrix operations lifted for backprop.
                 .
@@ -39,12 +39,13 @@
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wredundant-constraints
   build-depends:
       ANum >=0.2
-    , backprop >=0.1.2
+    , backprop >=0.1.4
     , base >=4.7 && <5
+    , finite-typelits
     , ghc-typelits-knownnat
     , ghc-typelits-natnormalise
     , hmatrix >=0.18
-    , hmatrix-vector-sized >=0.1
+    , hmatrix-vector-sized >=0.1.1
     , microlens
     , vector
     , vector-sized >=0.6
@@ -61,13 +62,13 @@
       test
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      backprop >=0.1.2
+      backprop >=0.1.4
     , base >=4.7 && <5
     , finite-typelits
     , hedgehog
     , hmatrix >=0.18
     , hmatrix-backprop
-    , hmatrix-vector-sized >=0.1
+    , hmatrix-vector-sized >=0.1.1
     , microlens
     , microlens-platform
     , vector-sized >=0.6
diff --git a/src/Numeric/LinearAlgebra/Static/Backprop.hs b/src/Numeric/LinearAlgebra/Static/Backprop.hs
--- a/src/Numeric/LinearAlgebra/Static/Backprop.hs
+++ b/src/Numeric/LinearAlgebra/Static/Backprop.hs
@@ -43,6 +43,8 @@
 -- functions are automatically backpropagatable.  Useful types are all
 -- re-exported.
 --
+-- Also contains 'sumElements' 'BVar' operation.
+--
 -- Formulas for gradients come from the following papers:
 --
 --     * https://people.maths.ox.ac.uk/gilesm/files/NA-08-01.pdf
@@ -77,10 +79,6 @@
 --     to handle these are at the moment.
 --     * 'H.withRows' and 'H.withColumns' made "type-safe", without
 --     existential types, with 'fromRows' and 'fromColumns'.
---
--- Some other notes:
---
---     * Added 'sumElements', as well, for convenience.
 
 module Numeric.LinearAlgebra.Static.Backprop (
   -- * Vector
@@ -150,10 +148,12 @@
   , dot
   , cross
   , diagR
+  , vmap
+  , vmap'
   , dvmap
-  , dvmap'
+  , mmap
+  , mmap'
   , dmmap
-  , dmmap'
   , outer
   , zipWithVector
   , zipWithVector'
@@ -179,26 +179,34 @@
   , mTm
   , unSym
   , (<·>)
+  -- * Backprop types re-exported
+  -- | Re-exported for convenience.
+  --
+  -- @since 0.1.1.0
+  , BVar
+  , Reifies
+  , W
   ) where
 
 import           Data.ANum
+import           Data.Bifunctor
 import           Data.Maybe
 import           Data.Proxy
 import           Foreign.Storable
 import           GHC.TypeLits
 import           Lens.Micro hiding                   ((&))
 import           Numeric.Backprop
-import           Numeric.Backprop.Op
 import           Numeric.Backprop.Tuple
 import           Unsafe.Coerce
+import qualified Data.Vector                         as V
 import qualified Data.Vector.Generic                 as VG
 import qualified Data.Vector.Generic.Sized           as SVG
 import qualified Data.Vector.Sized                   as SV
 import qualified Data.Vector.Storable.Sized          as SVS
 import qualified Numeric.LinearAlgebra               as HU
-import qualified Numeric.LinearAlgebra.Devel         as HU
 import qualified Numeric.LinearAlgebra.Static        as H
 import qualified Numeric.LinearAlgebra.Static.Vector as H
+import qualified Prelude.Backprop                    as B
 
 #if MIN_VERSION_base(4,11,0)
 import           Prelude hiding               ((<>))
@@ -209,9 +217,7 @@
     => BVar s H.ℝ
     -> BVar s H.ℝ
     -> BVar s (H.R 2)
-vec2 = liftOp2 $ opIsoN
-    (\(x ::< y ::< Ø)                -> H.vec2 x y     )
-    (\(HU.toList.H.extract->[dx,dy]) -> dx ::< dy ::< Ø)
+vec2 = isoVar2 H.vec2 (\(H.rVec->v) -> (SVS.index v 0, SVS.index v 1))
 {-# INLINE vec2 #-}
 
 vec3
@@ -220,9 +226,7 @@
     -> BVar s H.ℝ
     -> BVar s H.ℝ
     -> BVar s (H.R 3)
-vec3 = liftOp3 $ opIsoN
-    (\(x ::< y ::< z ::< Ø)             -> H.vec3 x y z          )
-    (\(HU.toList.H.extract->[dx,dy,dz]) -> dx ::< dy ::< dz ::< Ø)
+vec3 = isoVar3 H.vec3 (\(H.rVec->v) -> (SVS.index v 0, SVS.index v 1, SVS.index v 2))
 {-# INLINE vec3 #-}
 
 vec4
@@ -232,22 +236,17 @@
     -> BVar s H.ℝ
     -> BVar s H.ℝ
     -> BVar s (H.R 4)
-vec4 vX vY vZ vW = liftOp o (vX :< vY :< vZ :< vW :< Ø)
-  where
-    o :: Op '[H.ℝ, H.ℝ, H.ℝ, H.ℝ] (H.R 4)
-    o = opIsoN
-      (\(x ::< y ::< z ::< w ::< Ø)          -> H.vec4 x y z w               )
-      (\(HU.toList.H.extract->[dx,dy,dz,dw]) -> dx ::< dy ::< dz ::< dw ::< Ø)
-    {-# INLINE o #-}
+vec4 vX vY vZ vW = isoVarN
+    (\(x ::< y ::< z ::< w ::< Ø) -> H.vec4 x y z w)
+    (\(H.rVec->v) -> SVS.index v 0 ::< SVS.index v 1 ::< SVS.index v 2 ::< SVS.index v 3 ::< Ø)
+    (vX :< vY :< vZ :< vW :< Ø)
 {-# INLINE vec4 #-}
 
 (&) :: (Reifies s W, KnownNat n, 1 <= n, KnownNat (n + 1))
     => BVar s (H.R n)
     -> BVar s H.ℝ
     -> BVar s (H.R (n + 1))
-(&) = liftOp2 $ opIsoN
-    (\(xs ::< y ::< Ø)    -> xs H.& y                         )
-    (\(H.split->(dxs,dy)) -> dxs ::< fst (H.headTail dy) ::< Ø)
+(&) = isoVar2 (H.&) (\(H.split->(dxs,dy)) -> (dxs, fst (H.headTail dy)))
 infixl 4 &
 {-# INLINE (&) #-}
 
@@ -255,9 +254,7 @@
     => BVar s (H.R n)
     -> BVar s (H.R m)
     -> BVar s (H.R (n + m))
-(#) = liftOp2 $ opIsoN
-    (\(x ::< y ::< Ø)    -> x H.# y        )
-    (\(H.split->(dX,dY)) -> dX ::< dY ::< Ø)
+(#) = isoVar2 (H.#) H.split
 infixl 4 #
 {-# INLINE (#) #-}
 
@@ -267,9 +264,7 @@
     -> (BVar s (H.R p), BVar s (H.R (n - p)))
 split v = (t ^^. _1, t ^^. _2)      -- should we just return the T2 ?
   where
-    t = liftOp1 (opIso (tupT2 . H.split)
-                       (uncurryT2 (H.#))
-                ) v
+    t = isoVar (tupT2 . H.split) (uncurryT2 (H.#)) v
     {-# NOINLINE t #-}
 {-# INLINE split #-}
 
@@ -279,9 +274,9 @@
     -> (BVar s H.ℝ, BVar s (H.R (n - 1)))
 headTail v = (t ^^. _1, t ^^. _2)
   where
-    t = liftOp1 (opIso (tupT2 . H.headTail)
-                       (\(T2 d dx) -> (H.konst d :: H.R 1) H.# dx)
-                ) v
+    t = isoVar (tupT2 . H.headTail)
+               (\(T2 d dx) -> (H.konst d :: H.R 1) H.# dx)
+               v
     {-# NOINLINE t #-}
 {-# INLINE headTail #-}
 
@@ -290,9 +285,8 @@
     :: forall n s. (Reifies s W, KnownNat n)
     => SV.Vector n (BVar s H.ℝ)
     -> BVar s (H.R n)
-vector vs =
-    liftOp1 (opIso (H.vecR . SVG.convert) (SVG.convert . H.rVec))
-            (collectVar vs)
+vector = isoVar (H.vecR . SVG.convert) (SVG.convert . H.rVec)
+       . collectVar
 {-# INLINE vector #-}
 
 linspace
@@ -312,22 +306,20 @@
 row :: (Reifies s W, KnownNat n)
     => BVar s (H.R n)
     -> BVar s (H.L 1 n)
-row = liftOp1 $ opIso H.row H.unrow
+row = isoVar H.row H.unrow
 {-# INLINE row #-}
 
 col :: (Reifies s W, KnownNat n)
     => BVar s (H.R n)
     -> BVar s (H.L n 1)
-col = liftOp1 $ opIso H.col H.uncol
+col = isoVar H.col H.uncol
 {-# INLINE col #-}
 
 (|||) :: (Reifies s W, KnownNat c, KnownNat r1, KnownNat (r1 + r2))
       => BVar s (H.L c r1)
       -> BVar s (H.L c r2)
       -> BVar s (H.L c (r1 + r2))
-(|||) = liftOp2 $ opIsoN
-    (\(x ::< y ::< Ø)        -> x H.||| y        )
-    (\(H.splitCols->(dX,dY)) -> dX ::< dY ::< Ø)
+(|||) = isoVar2 (H.|||) H.splitCols
 infixl 3 |||
 {-# INLINE (|||) #-}
 
@@ -335,9 +327,7 @@
       => BVar s (H.L r1        c)
       -> BVar s (H.L r2        c)
       -> BVar s (H.L (r1 + r2) c)
-(===) = liftOp2 $ opIsoN
-    (\(x ::< y ::< Ø)        -> x H.=== y        )
-    (\(H.splitRows->(dX,dY)) -> dX ::< dY ::< Ø)
+(===) = isoVar2 (H.===) H.splitRows
 infixl 2 ===
 {-# INLINE (===) #-}
 
@@ -347,9 +337,7 @@
     -> (BVar s (H.L p n), BVar s (H.L (m - p) n))
 splitRows v = (t ^^. _1, t ^^. _2)
   where
-    t = liftOp1 (opIso (tupT2 . H.splitRows)
-                       (\(T2 dx dy) -> dx H.=== dy)
-                ) v
+    t = isoVar (tupT2 . H.splitRows) (uncurryT2 (H.===)) v
     {-# NOINLINE t #-}
 {-# INLINE splitRows #-}
 
@@ -359,9 +347,7 @@
     -> (BVar s (H.L m p), BVar s (H.L m (n - p)))
 splitCols v = (t ^^. _1, t ^^. _2)
   where
-    t = liftOp1 (opIso (tupT2 . H.splitCols)
-                       (uncurryT2 (H.|||))
-                ) v
+    t = isoVar (tupT2 . H.splitCols) (uncurryT2 (H.|||)) v
     {-# NOINLINE t #-}
 {-# INLINE splitCols #-}
 
@@ -369,20 +355,20 @@
     :: (Reifies s W, KnownNat n)
     => BVar s (H.L 1 n)
     -> BVar s (H.R n)
-unrow = liftOp1 $ opIso H.unrow H.row
+unrow = isoVar H.unrow H.row
 {-# INLINE unrow #-}
 
 uncol
     :: (Reifies s W, KnownNat n)
     => BVar s (H.L n 1)
     -> BVar s (H.R n)
-uncol = liftOp1 $ opIso H.uncol H.col
+uncol = isoVar H.uncol H.col
 {-# INLINE uncol #-}
 
 tr  :: (Reifies s W, HU.Transposable m mt, HU.Transposable mt m, Num m, Num mt)
     => BVar s m
     -> BVar s mt
-tr = liftOp1 $ opIso H.tr H.tr
+tr = isoVar H.tr H.tr
 {-# INLINE tr #-}
 
 diag
@@ -397,15 +383,9 @@
     :: forall m n s. (Reifies s W, KnownNat m, KnownNat n)
     => [BVar s H.ℝ]
     -> BVar s (H.L m n)
-matrix vs = case SV.fromList @(m * n) vs of
-    Nothing  -> error "matrix: invalid number of elements"
-    Just vs' ->
-        liftOp1 (opIso (fromJust . H.create . HU.reshape n . VG.convert . SV.fromSized)
-                       (SV.concatMap (SVG.convert . H.rVec) . H.lRows)
-                )
-                (collectVar vs')
-  where
-    n = fromInteger $ natVal (Proxy @n)
+matrix = maybe (error "matrix: invalid number of elements")
+               (isoVar (H.vecL . SVG.convert) (SVG.convert . H.lVec) . collectVar)
+       . SV.fromList @(m * n)
 {-# INLINE matrix #-}
 
 -- | Matrix product
@@ -808,29 +788,43 @@
     )
 {-# INLINE diagR #-}
 
-dvmap
+-- | Note: if possible, use the potentially much more performant 'vmap''.
+vmap
     :: ( Reifies s W
+       , KnownNat n
+       )
+    => (BVar s Double -> BVar s Double)
+    -> BVar s (H.R n)
+    -> BVar s (H.R n)
+vmap f = isoVar (H.vecR . SVG.convert @V.Vector) (SVG.convert . H.rVec)
+       . B.fmap f
+       . isoVar (SVG.convert . H.rVec) (H.vecR . SVG.convert)
+{-# INLINE vmap #-}
+
+-- | 'vmap', but potentially more performant.  Only usable if the mapped
+-- function does not depend on any external 'BVar's.
+vmap'
+    :: ( Reifies s W
        , Num (vec n)
        , Storable field
-       , Storable (field, field)
        , H.Sized field (vec n) HU.Vector
        )
     => (forall s'. Reifies s' W => BVar s' field -> BVar s' field)
     -> BVar s (vec n)
     -> BVar s (vec n)
-dvmap f = liftOp1 . op1 $ \x ->
-    let (y, dx) = HU.unzipVector $ VG.map (backprop f) (H.extract x)
-    in  ( fromJust (H.create y)
-        , \d -> d * fromJust (H.create dx)
-        )
-{-# INLINE dvmap #-}
+vmap' f = liftOp1 . op1 $ bimap (fromJust . H.create . VG.convert)
+                                ((*) . fromJust . H.create . VG.convert)
+                        . V.unzip
+                        . V.map (backprop f)
+                        . VG.convert
+                        . H.extract
+{-# INLINE vmap' #-}
 
 -- TODO: Can be made more efficient if backprop exports
 -- a custom-total-derivative version
 
--- | A version of 'dvmap' that is less performant but is based on
--- 'H.zipWithVector' from 'H.Domain'.
-dvmap'
+-- | Note: Potentially less performant than 'vmap''.
+dvmap
     :: ( Reifies s W
        , KnownNat n
        , H.Domain field vec mat
@@ -840,38 +834,53 @@
     => (forall s'. Reifies s' W => BVar s' field -> BVar s' field)
     -> BVar s (vec n)
     -> BVar s (vec n)
-dvmap' f = liftOp1 . op1 $ \x ->
+dvmap f = liftOp1 . op1 $ \x ->
     ( H.dvmap (evalBP f) x
     , (H.dvmap (gradBP f) x *)
     )
-{-# INLINE dvmap' #-}
+{-# INLINE dvmap #-}
 
-dmmap
+-- | Note: if possible, use the potentially much more performant 'mmap''.
+mmap
+    :: ( Reifies s W
+       , KnownNat n
+       , KnownNat m
+       )
+    => (BVar s Double -> BVar s Double)
+    -> BVar s (H.L n m)
+    -> BVar s (H.L n m)
+mmap f = isoVar (H.vecL . SVG.convert @V.Vector) (SVG.convert . H.lVec)
+       . B.fmap f
+       . isoVar (SVG.convert . H.lVec) (H.vecL . SVG.convert)
+{-# INLINE mmap #-}
+
+-- | 'mmap', but potentially more performant.  Only usable if the mapped
+-- function does not depend on any external 'BVar's.
+mmap'
     :: forall n m mat field s.
        ( Reifies s W
        , KnownNat m
        , Num (mat n m)
-       , Storable (field, field)
        , H.Sized field (mat n m) HU.Matrix
        , HU.Element field
        )
     => (forall s'. Reifies s' W => BVar s' field -> BVar s' field)
     -> BVar s (mat n m)
     -> BVar s (mat n m)
-dmmap f = liftOp1 . op1 $ \x ->
-    let (y', dx') = HU.unzipVector
-                  . VG.map (backprop f)
-                  . HU.flatten
-                  $ H.extract x
-    in  ( fromJust . H.create . HU.reshape m $ y'
-        , \d -> (* d) . fromJust . H.create . HU.reshape m $ dx'
-        )
+mmap' f = liftOp1 . op1 $ bimap (fromJust . H.create . HU.reshape m . VG.convert)
+                                ((*) . fromJust . H.create . HU.reshape m . VG.convert)
+                        . V.unzip
+                        . V.map (backprop f)
+                        . VG.convert
+                        . HU.flatten
+                        . H.extract
   where
     m :: Int
     m = fromInteger $ natVal (Proxy @m)
-{-# INLINE dmmap #-}
+{-# INLINE mmap' #-}
 
-dmmap'
+-- | Note: Potentially less performant than 'mmap''.
+dmmap
     :: ( Reifies s W
        , KnownNat n
        , KnownNat m
@@ -882,11 +891,11 @@
     => (forall s'. Reifies s' W => BVar s' field -> BVar s' field)
     -> BVar s (mat n m)
     -> BVar s (mat n m)
-dmmap' f = liftOp1 . op1 $ \x ->
+dmmap f = liftOp1 . op1 $ \x ->
     ( H.dmmap (evalBP f) x
     , (H.dmmap (gradBP f) x *)
     )
-{-# INLINE dmmap' #-}
+{-# INLINE dmmap #-}
 
 outer
     :: ( Reifies s W
@@ -1031,28 +1040,28 @@
     :: forall m n s. (Reifies s W, KnownNat m, KnownNat n)
     => BVar s (H.L m n)
     -> SV.Vector m (BVar s (H.R n))
-toRows = sequenceVar . liftOp1 (opIso H.lRows H.rowsL)
+toRows = sequenceVar . isoVar H.lRows H.rowsL
 {-# INLINE toRows #-}
 
 toColumns
     :: forall m n s. (Reifies s W, KnownNat m, KnownNat n)
     => BVar s (H.L m n)
     -> SV.Vector n (BVar s (H.R m))
-toColumns = sequenceVar . liftOp1 (opIso H.lCols H.colsL)
+toColumns = sequenceVar . isoVar H.lCols H.colsL
 {-# INLINE toColumns #-}
 
 fromRows
     :: forall m n s. (Reifies s W, KnownNat m, KnownNat n)
     => SV.Vector m (BVar s (H.R n))
     -> BVar s (H.L m n)
-fromRows = liftOp1 (opIso H.rowsL H.lRows) . collectVar
+fromRows = isoVar H.rowsL H.lRows . collectVar
 {-# INLINE fromRows #-}
 
 fromColumns
     :: forall m n s. (Reifies s W, KnownNat m, KnownNat n)
     => SV.Vector n (BVar s (H.R m))
     -> BVar s (H.L m n)
-fromColumns = liftOp1 (opIso H.colsL H.lCols) . collectVar
+fromColumns = isoVar H.colsL H.lCols . collectVar
 {-# INLINE fromColumns #-}
 
 konst
@@ -1142,9 +1151,10 @@
     :: forall t s d q. (Reifies q W, H.Sized t s d, Num s, Num (d t))
     => BVar q (d t)
     -> Maybe (BVar q s)
-create = fmap (unANum . sequenceVar) . liftOp1 $
-    opIso (ANum              . H.create)
-          (maybe 0 H.extract . unANum  )
+create = unANum
+       . sequenceVar
+       . isoVar (ANum              . H.create)
+                (maybe 0 H.extract . unANum  )
 {-# INLINE create #-}
 
 
@@ -1198,7 +1208,7 @@
     :: (Reifies s W, KnownNat n)
     => BVar s (H.Sym n)
     -> BVar s (H.Sq n)
-unSym = liftOp1 (opIso H.unSym unsafeCoerce)
+unSym = isoVar H.unSym unsafeCoerce
 {-# INLINE unSym #-}
 
 -- | Unicode synonym for '<.>>'
