diff --git a/DDF/Combine.hs b/DDF/Combine.hs
deleted file mode 100644
--- a/DDF/Combine.hs
+++ /dev/null
@@ -1,145 +0,0 @@
-{-# LANGUAGE
-  NoImplicitPrelude,
-  TypeFamilies,
-  TypeApplications,
-  ScopedTypeVariables,
-  NoMonomorphismRestriction,
-  MultiParamTypeClasses,
-  FlexibleInstances,
-  FlexibleContexts
-#-}
-
-module DDF.Combine where
-
-import DDF.Meta.Interpreter
-import qualified DDF.Map as Map
-import DDF.Lang
-import qualified DDF.VectorTF as VTF
-
-instance (DBI l, DBI r) => DBI (Combine l r) where
-  z = Combine z z
-  s (Combine l r) = Combine (s l) (s r)
-  app (Combine fl fr) (Combine xl xr) = Combine (app fl xl) (app fr xr)
-  abs (Combine l r) = Combine (abs l) (abs r)
-  hoas f = Combine (hoas $ \x -> case f (Combine x z) of Combine l _ -> l) (hoas $ \x -> case f (Combine z x) of Combine _ r -> r)
-
-instance (Bool l, Bool r) => Bool (Combine l r) where
-  bool x = Combine (bool x) (bool x)
-  ite = Combine ite ite
-
-instance (Char l, Char r) => Char (Combine l r) where
-  char x = Combine (char x) (char x)
-
-instance (Prod l, Prod r) => Prod (Combine l r) where
-  mkProd = Combine mkProd mkProd
-  zro = Combine zro zro
-  fst = Combine fst fst
-
-instance (Double l, Double r) => Double (Combine l r) where
-  double x = Combine (double x) (double x)
-  doublePlus = Combine doublePlus doublePlus
-  doubleMinus = Combine doubleMinus doubleMinus
-  doubleMult = Combine doubleMult doubleMult
-  doubleDivide = Combine doubleDivide doubleDivide
-  doubleExp = Combine doubleExp doubleExp
-  doubleEq = Combine doubleEq doubleEq
-
-instance (Float l, Float r) => Float (Combine l r) where
-  float x = Combine (float x) (float x)
-  floatPlus = Combine floatPlus floatPlus
-  floatMinus = Combine floatMinus floatMinus
-  floatMult = Combine floatMult floatMult
-  floatDivide = Combine floatDivide floatDivide
-  floatExp = Combine floatExp floatExp
-
-instance (Option l, Option r) => Option (Combine l r) where
-  nothing = Combine nothing nothing
-  just = Combine just just
-  optionMatch = Combine optionMatch optionMatch
-
-instance (Map.Map l, Map.Map r) => Map.Map (Combine l r) where
-  empty = Combine Map.empty Map.empty
-  lookup = Combine Map.lookup Map.lookup
-  singleton = Combine Map.singleton Map.singleton
-  alter = Combine Map.alter Map.alter
-  mapMap = Combine Map.mapMap Map.mapMap
-  unionWith = Combine Map.unionWith Map.unionWith
-
-instance (Bimap l, Bimap r) => Bimap (Combine l r) where
-  size = Combine size size
-  empty = Combine empty empty
-  singleton = Combine singleton singleton
-  lookupL = Combine lookupL lookupL
-  lookupR = Combine lookupR lookupR
-  toMapL = Combine toMapL toMapL
-  toMapR = Combine toMapR toMapR
-  insert = Combine insert insert
-  updateL = Combine updateL updateL
-  updateR = Combine updateR updateR
-
-instance (Dual l, Dual r) => Dual (Combine l r) where
-  dual = Combine dual dual
-  runDual = Combine runDual runDual
-
-instance (Unit l, Unit r) => Unit (Combine l r) where
-  unit = Combine unit unit
-
-instance (Sum l, Sum r) => Sum (Combine l r) where
-  left = Combine left left
-  right = Combine right right
-  sumMatch = Combine sumMatch sumMatch
-
-instance (Int l, Int r) => Int (Combine l r) where
-  int x = Combine (int x) (int x)
-  pred = Combine pred pred
-  isZero = Combine isZero isZero
-
-instance (Y l, Y r) => Y (Combine l r) where
-  y = Combine y y
-
-instance (List l, List r) => List (Combine l r) where
-  nil = Combine nil nil
-  cons = Combine cons cons
-  listMatch = Combine listMatch listMatch
-
-instance (Functor l m, Functor r m) => Functor (Combine l r) m where
-  map = Combine map map
-
-instance (Applicative l m, Applicative r m) => Applicative (Combine l r) m where
-  pure = Combine pure pure
-  ap = Combine ap ap
-
-instance (Monad l m, Monad r m) => Monad (Combine l r) m where
-  bind = Combine bind bind
-  join = Combine join join
-
-instance (IO l, IO r) => IO (Combine l r) where
-  putStrLn = Combine putStrLn putStrLn
-
-instance (VTF.VectorTF l, VTF.VectorTF r) => VTF.VectorTF (Combine l r) where
-  zero = Combine VTF.zero VTF.zero
-  basis = Combine VTF.basis VTF.basis
-  plus = Combine VTF.plus VTF.plus
-  mult = Combine VTF.mult VTF.mult
-  vtfMatch = Combine VTF.vtfMatch VTF.vtfMatch
-
-instance (DiffWrapper l, DiffWrapper r) => DiffWrapper (Combine l r) where
-  diffWrapper = Combine diffWrapper diffWrapper
-  runDiffWrapper = Combine runDiffWrapper runDiffWrapper
-
-instance (Fix l, Fix r) => Fix (Combine l r) where
-  fix = Combine fix fix
-  runFix = Combine runFix runFix
-
-instance (FreeVector l, FreeVector r) => FreeVector (Combine l r) where
-  freeVector = Combine freeVector freeVector
-  runFreeVector = Combine runFreeVector runFreeVector
-
-instance (Lang l, Lang r) => Lang (Combine l r) where
-  exfalso = Combine exfalso exfalso
-  runWriter = Combine runWriter runWriter
-  writer = Combine writer writer
-  double2Float = Combine double2Float double2Float
-  float2Double = Combine float2Double float2Double
-  state = Combine state state
-  runState = Combine runState runState
diff --git a/DDF/GDiff.hs b/DDF/GDiff.hs
deleted file mode 100644
--- a/DDF/GDiff.hs
+++ /dev/null
@@ -1,145 +0,0 @@
-{-# LANGUAGE
-  NoImplicitPrelude,
-  RankNTypes,
-  InstanceSigs,
-  ScopedTypeVariables,
-  TypeFamilies,
-  TypeApplications,
-  MultiParamTypeClasses,
-  FlexibleInstances,
-  FlexibleContexts
-#-}
-
-module DDF.GDiff where
-import DDF.Lang
-import qualified Prelude as M
-import DDF.Diff ()
-import qualified DDF.Map as Map
-import qualified DDF.VectorTF as VTF
-
-instance DBI r => DBI (GDiff r) where
-  z = GDiff (M.const z)
-  s (GDiff x) = GDiff (\p -> s $ x p)
-  app (GDiff f) (GDiff x) = GDiff (\p -> app (f p) (x p))
-  abs (GDiff x) = GDiff (\p -> abs $ x p)
-
-instance Bool r => Bool (GDiff r) where
-  bool x = GDiff $ M.const $ bool x
-  ite = GDiff $ M.const ite
-
-instance Char r => Char (GDiff r) where
-  char x = GDiff $ M.const $ char x
-
-instance Prod r => Prod (GDiff r) where
-  mkProd = GDiff (M.const mkProd)
-  zro = GDiff $ M.const zro
-  fst = GDiff $ M.const fst
-
-instance Dual r => Dual (GDiff r) where
-  dual = GDiff $ M.const $ dual
-  runDual = GDiff $ M.const $ runDual
-
-instance Lang r => Double (GDiff r) where
-  double x = GDiff $ M.const $ double x
-  doublePlus = GDiff $ M.const $ doublePlus
-  doubleMinus = GDiff $ M.const $ doubleMinus
-  doubleMult = GDiff $ M.const $ doubleMult
-  doubleDivide = GDiff $ M.const $ doubleDivide
-  doubleExp = GDiff $ M.const $ doubleExp
-  doubleEq = GDiff $ M.const $ doubleEq
-
-instance Lang r => VTF.VectorTF (GDiff r) where
-  zero = GDiff $ M.const $ VTF.zero
-  basis = GDiff $ M.const $ VTF.basis
-  plus = GDiff $ M.const $ VTF.plus
-  mult = GDiff $ M.const $ VTF.mult
-  vtfMatch = GDiff $ M.const $ VTF.vtfMatch
-
-instance Lang r => Float (GDiff r) where
-  float x = GDiff $ M.const $ float x
-  floatPlus = GDiff $ M.const $ floatPlus
-  floatMinus = GDiff $ M.const $ floatMinus
-  floatMult = GDiff $ M.const $ floatMult
-  floatDivide = GDiff $ M.const $ floatDivide
-  floatExp = GDiff $ M.const $ floatExp
-
-instance Option r => Option (GDiff r) where
-  nothing = GDiff $ M.const nothing
-  just = GDiff $ M.const just
-  optionMatch = GDiff $ M.const optionMatch
-
-instance Map.Map r => Map.Map (GDiff r) where
-  empty = GDiff $ M.const Map.empty
-  singleton = GDiff $ M.const Map.singleton
-  lookup = GDiff $ M.const Map.lookup
-  alter = GDiff $ M.const Map.alter
-  mapMap = GDiff $ M.const Map.mapMap
-  unionWith = GDiff $ M.const Map.unionWith
-
-instance Bimap r => Bimap (GDiff r) where
-  size = GDiff $ M.const size
-  lookupL = GDiff $ M.const lookupL
-  lookupR = GDiff $ M.const lookupR
-  empty = GDiff $ M.const empty
-  singleton = GDiff $ M.const singleton
-  insert = GDiff $ M.const insert
-  updateL = GDiff $ M.const updateL
-  updateR = GDiff $ M.const updateR
-  toMapL = GDiff $ M.const toMapL
-  toMapR = GDiff $ M.const toMapR
-
-instance Unit r => Unit (GDiff r) where
-  unit = GDiff $ M.const unit
-
-instance Sum r => Sum (GDiff r) where
-  left = GDiff $ M.const left
-  right = GDiff $ M.const right
-  sumMatch = GDiff $ M.const sumMatch
-
-instance Int r => Int (GDiff r) where
-  int x = GDiff $ M.const $ int x
-  pred = GDiff $ M.const pred
-  isZero = GDiff $ M.const isZero
-
-instance Y r => Y (GDiff r) where
-  y = GDiff $ M.const y
-
-instance Functor r M.IO => Functor (GDiff r) M.IO where
-  map = GDiff $ M.const map
-
-instance Applicative r M.IO => Applicative (GDiff r) M.IO where
-  pure = GDiff $ M.const pure
-  ap = GDiff $ M.const ap
-
-instance Monad r M.IO => Monad (GDiff r) M.IO where
-  bind = GDiff $ M.const bind
-  join = GDiff $ M.const join
-
-instance IO r => IO (GDiff r) where
-  putStrLn = GDiff $ M.const putStrLn
-
-instance List r => List (GDiff r) where
-  nil = GDiff $ M.const nil
-  cons = GDiff $ M.const cons
-  listMatch = GDiff $ M.const listMatch
-
-instance DiffWrapper r => DiffWrapper (GDiff r) where
-  diffWrapper = GDiff $ M.const diffWrapper
-  runDiffWrapper = GDiff $ M.const runDiffWrapper
-
-instance DiffWrapper r => Fix (GDiff r) where
-  fix = GDiff $ M.const fix
-  runFix = GDiff $ M.const runFix
-
-instance FreeVector r => FreeVector (GDiff r) where
-  freeVector = GDiff $ M.const freeVector
-  runFreeVector = GDiff $ M.const runFreeVector
-
-instance Lang r => Lang (GDiff r) where
-  exfalso = GDiff $ M.const exfalso
-  writer = GDiff $ M.const writer
-  runWriter = GDiff $ M.const runWriter
-  float2Double = GDiff $ M.const float2Double
-  double2Float = GDiff $ M.const double2Float
-  state = GDiff $ M.const state
-  runState = GDiff $ M.const runState
diff --git a/DDF/Meta/Diff.hs b/DDF/Meta/Diff.hs
--- a/DDF/Meta/Diff.hs
+++ b/DDF/Meta/Diff.hs
@@ -19,6 +19,4 @@
 
 type family DiffType (v :: *) (x :: *)
 
-newtype GDiff r h x = GDiff {runGDiff :: forall v. Vector r v => Proxy v -> Diff r v h x}
-
 newtype Diff r v h x = Diff {runDiff :: r (DiffType v h) (DiffType v x)}
diff --git a/DDF/Meta/Interpreter.hs b/DDF/Meta/Interpreter.hs
--- a/DDF/Meta/Interpreter.hs
+++ b/DDF/Meta/Interpreter.hs
@@ -15,11 +15,6 @@
 
 newtype Eval h x = Eval {runEval :: h -> x}
 
-data Combine l r h x = Combine (l h x) (r h x)
-
-combineLeft (Combine l _) = l
-combineRight (Combine _ r) = r
-
 newtype UnHOAS repr h x = UnHOAS {runUnHOAS :: repr h x}
 
 class ProdCon con l r where
diff --git a/DDF/Term.hs b/DDF/Term.hs
new file mode 100644
--- /dev/null
+++ b/DDF/Term.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE
+  NoImplicitPrelude,
+  TemplateHaskell,
+  MultiParamTypeClasses
+#-}
+
+module DDF.Term (module DDF.TermGen) where
+import DDF.TermGen
+
+$genInstance
diff --git a/DDF/TermGen.hs b/DDF/TermGen.hs
new file mode 100644
--- /dev/null
+++ b/DDF/TermGen.hs
@@ -0,0 +1,255 @@
+{-# LANGUAGE
+  RankNTypes,
+  ConstraintKinds,
+  NoImplicitPrelude,
+  KindSignatures,
+  TypeOperators,
+  MultiParamTypeClasses,
+  FlexibleContexts,
+  UndecidableInstances,
+  FlexibleInstances,
+  TypeFamilies,
+  UndecidableSuperClasses,
+  TemplateHaskell,
+  TypeApplications,
+  ScopedTypeVariables,
+  PartialTypeSignatures,
+  AllowAmbiguousTypes
+#-}
+
+module DDF.TermGen (module DDF.TermGen, module DDF.Lang) where
+
+import DDF.Lang
+import qualified DDF.Map as Map
+import qualified DDF.VectorTF as VTF
+
+import qualified Prelude as M
+import Language.Haskell.TH
+
+type family SubLC (l :: (* -> * -> *) -> Constraint) (r :: (* -> * -> *) -> Constraint) :: Constraint
+
+class SubLC l r => SubL l r where
+  sub :: forall repr. l repr :- r repr
+
+newtype Term c h s = Term { runTerm :: forall r. c r => r h s }
+
+mkT :: forall r l h s. (SubL l r) =>
+  (forall (repr :: * -> * -> *). (l repr, r repr) => repr h s) ->
+  Term l h s
+
+mkT f = Term k
+  where
+    k :: forall repr. l repr => repr h s
+    k = f @repr \\ sub @l @r @repr
+
+type instance SubLC c DBI = ()
+
+instance SubL c DBI => DBI (Term c) where
+  z = mkT @DBI z
+  s (Term x) = mkT @DBI (s x)
+  abs (Term x) = mkT @DBI (abs x)
+  app (Term f) (Term x) = mkT @DBI (app f x)
+
+type instance SubLC c Bool = SubL c DBI
+
+instance SubL c Bool => Bool (Term c) where
+  ite = mkT @Bool ite
+  bool x = mkT @Bool (bool x)
+
+type instance SubLC c Int = SubL c Bool
+
+instance SubL c Int => Int (Term c) where
+  pred = mkT @Int pred
+  int x = mkT @Int (int x)
+  isZero = mkT @Int isZero
+
+type instance SubLC c Fix = SubL c DBI
+
+instance SubL c Fix => Fix (Term c) where
+  fix = mkT @Fix fix
+  runFix = mkT @Fix runFix
+
+type instance SubLC c Lang = (
+  SubL c Fix,
+  SubL c Int,
+  SubL c Float,
+  SubL c Double,
+  SubL c Bimap,
+  SubL c IO,
+  SubL c Sum,
+  SubL c Dual,
+  SubL c DiffWrapper,
+  SubL c FreeVector,
+  SubL c VTF.VectorTF)
+
+instance SubL c Lang => Lang (Term c) where
+  state = mkT @Lang state
+  writer = mkT @Lang writer
+  exfalso = mkT @Lang exfalso
+  runState = mkT @Lang runState
+  runWriter = mkT @Lang runWriter
+  float2Double = mkT @Lang float2Double
+  double2Float = mkT @Lang double2Float
+
+type instance SubLC c FreeVector = SubL c DBI
+
+instance SubL c FreeVector => FreeVector (Term c) where
+  freeVector = mkT @FreeVector freeVector
+  runFreeVector = mkT @FreeVector runFreeVector
+
+type instance SubLC c DiffWrapper = SubL c DBI
+
+instance SubL c DiffWrapper => DiffWrapper (Term c) where
+  diffWrapper = mkT @DiffWrapper diffWrapper
+  runDiffWrapper = mkT @DiffWrapper runDiffWrapper
+
+type instance SubLC c Char = SubL c DBI
+
+instance SubL c Char => Char (Term c) where
+  char x = mkT @Char (char x)
+
+type instance SubLC c Bimap = (SubL c Int, SubL c Map.Map)
+
+instance SubL c Bimap => Bimap (Term c) where
+  size = mkT @Bimap size
+  empty = mkT @Bimap empty
+  insert = mkT @Bimap insert
+  toMapL = mkT @Bimap toMapL
+  toMapR = mkT @Bimap toMapR
+  lookupL = mkT @Bimap lookupL
+  lookupR = mkT @Bimap lookupR
+  updateL = mkT @Bimap updateL
+  updateR = mkT @Bimap updateR
+  singleton = mkT @Bimap singleton
+
+type instance SubLC c Float = SubL c DBI
+
+instance SubL c Float => Float (Term c) where
+  float x = mkT @Float (float x) 
+  floatExp = mkT @Float floatExp
+  floatPlus = mkT @Float floatPlus
+  floatMult = mkT @Float floatMult
+  floatMinus = mkT @Float floatMinus
+  floatDivide = mkT @Float floatDivide
+
+type instance SubLC c Double = SubL c Bool
+
+instance SubL c Double => Double (Term c) where
+  doubleEq = mkT @Double doubleEq
+  double x = mkT @Double (double x)
+  doubleExp = mkT @Double doubleExp
+  doublePlus = mkT @Double doublePlus  
+  doubleMult = mkT @Double doubleMult
+  doubleMinus = mkT @Double doubleMinus
+  doubleDivide = mkT @Double doubleDivide
+
+type instance SubLC c Dual = SubL c Prod
+
+instance SubL c Dual => Dual (Term c) where
+  dual = mkT @Dual dual
+  runDual = mkT @Dual runDual
+
+type instance SubLC c Unit = SubL c DBI
+
+instance SubL c Unit => Unit (Term c) where
+  unit = mkT @Unit unit
+
+type instance SubLC c Sum = SubL c DBI
+
+instance SubL c Sum => Sum (Term c) where
+  left = mkT @Sum left
+  right = mkT @Sum right
+  sumMatch = mkT @Sum sumMatch
+
+type instance SubLC c IO = (SubL c Unit, SubL c Char, SubL c List)
+
+instance SubL c IO => IO (Term c) where
+  putStrLn = mkT @IO putStrLn
+
+instance SubL c IO => Functor (Term c) M.IO where
+  map = mkT @IO map
+
+instance SubL c IO => Applicative (Term c) M.IO where
+  ap = mkT @IO ap
+  pure = mkT @IO pure
+
+instance SubL c IO => Monad (Term c) M.IO where
+  join = mkT @IO join
+  bind = mkT @IO bind
+
+type instance SubLC c List = SubL c Y
+
+instance SubL c List => List (Term c) where
+  nil = mkT @List nil
+  cons = mkT @List cons
+  listMatch = mkT @List listMatch
+
+type instance SubLC c Prod = SubL c DBI
+
+instance SubL c Prod => Prod (Term c) where
+  zro = mkT @Prod zro
+  fst = mkT @Prod fst
+  mkProd = mkT @Prod mkProd
+
+type instance SubLC c Y = SubL c DBI
+
+instance SubL c Y => Y (Term c) where
+  y = mkT @Y y
+
+type instance SubLC c Map.Map = (SubL c Prod, SubL c Option)
+
+instance SubL c Map.Map => Map.Map (Term c) where
+  empty = mkT @Map.Map Map.empty
+  alter = mkT @Map.Map Map.alter
+  lookup = mkT @Map.Map Map.lookup 
+  mapMap = mkT @Map.Map Map.mapMap
+  singleton = mkT @Map.Map Map.singleton
+  unionWith = mkT @Map.Map Map.unionWith
+
+type instance SubLC c VTF.VectorTF = SubL c Double
+
+instance SubL c VTF.VectorTF => VTF.VectorTF (Term c) where
+  zero = mkT @VTF.VectorTF VTF.zero
+  plus = mkT @VTF.VectorTF VTF.plus
+  mult = mkT @VTF.VectorTF VTF.mult
+  basis = mkT @VTF.VectorTF VTF.basis
+  vtfMatch = mkT @VTF.VectorTF VTF.vtfMatch
+
+type instance SubLC c Option = SubL c DBI
+
+instance SubL c Option => Option (Term c) where
+  just = mkT @Option just
+  nothing = mkT @Option nothing
+  optionMatch = mkT @Option optionMatch
+
+genInstance :: Q [Dec]
+genInstance =
+  M.mapM gen [
+    ''DBI,
+    ''Double,
+    ''Bool,
+    ''Lang,
+    ''Fix,
+    ''Int,
+    ''Char,
+    ''Float,
+    ''VTF.VectorTF,
+    ''Map.Map,
+    ''Bimap,
+    ''Prod,
+    ''IO,
+    ''Unit,
+    ''Option,
+    ''Sum,
+    ''List,
+    ''Y,
+    ''Dual,
+    ''DiffWrapper,
+    ''FreeVector]
+    where
+      gen n = M.return $
+        InstanceD
+          M.Nothing
+          []
+          (AppT (AppT (ConT ''SubL) (ConT ''Lang)) (ConT n))
+          [ValD (VarP 'sub) (NormalB (AppE (ConE 'Sub) (ConE 'Dict))) []]
diff --git a/DDF/Xor.lhs b/DDF/Xor.lhs
--- a/DDF/Xor.lhs
+++ b/DDF/Xor.lhs
@@ -1,4 +1,11 @@
-> {-# LANGUAGE ScopedTypeVariables, NoMonomorphismRestriction, TypeApplications, RankNTypes, NoImplicitPrelude #-}
+> {-# LANGUAGE
+>   ScopedTypeVariables,
+>   NoMonomorphismRestriction,
+>   TypeApplications,
+>   RankNTypes,
+>   NoImplicitPrelude,
+>   ScopedTypeVariables
+> #-}
 
 This is the classical example of using sigmoid NN to approximate Xor.
 You should already read DDF.Poly before this.
@@ -7,14 +14,12 @@
 > import qualified Prelude as M
 > import System.Random
 > import Control.Monad (when)
-> import Data.Proxy
 > import Data.Constraint
 > import DDF.Util
 > import DDF.Lang
 > import DDF.Show
-> import DDF.Combine ()
 > import DDF.Eval ()
-> import DDF.GDiff ()
+> import DDF.Term
 > import DDF.ImpW
 > import DDF.WithDiff
 > import qualified DDF.Meta.Dual as M
@@ -94,8 +99,8 @@
 
 > findXor :: forall g m. (RandomGen g, M.Monad m) => g -> (AST -> m ()) -> (M.Int -> M.Double -> M.String -> m ()) -> m XOR
 > findXor rand doAST doIter = case runImpW $ noEnv xorNet of
->   RunImpW ((Combine (Show xorS) (Combine (Eval xorEv) xorE)) :: Weight w => Combine Show (Combine Eval (GDiff Eval)) () (w -> XOR)) -> do
->     doAST $ xorS vars 0
+>   RunImpW ((Term net) :: Weight w => Term Lang () (w -> XOR)) -> do
+>     doAST $ runShow net vars 0
 
 printing weights. now you will see a list of gibberish
 
@@ -103,11 +108,11 @@
 
 Getting random weights...
 
->     (go (diff xorE) initWeight (runEval selfWithDiff () \\ weightCon @w @(WithDiff Eval)) (diff loss)
->         ((runEval (lam3 $ \d o n -> minus2 o (mult2 d n)) ()) \\ weightCon @w @(Vector Eval)) 0 (xorEv ())) \\ weightCon @w @M.Show
+>     (go (diff net) initWeight (runEval selfWithDiff () \\ weightCon @w @(WithDiff Eval)) (diff loss)
+>         ((runEval (lam3 $ \d o n -> minus2 o (mult2 d n)) ()) \\ weightCon @w @(Vector Eval)) 0 (runEval net ())) \\ weightCon @w @M.Show
 >     where
->       diff :: GDiff Eval () x -> DiffType w x
->       diff x = ((runEval (runDiff (runGDiff x (Proxy :: Proxy w))) ()) \\ weightCon @w @(Vector Eval))
+>       diff :: forall x. Term Lang () x -> DiffType w x
+>       diff (Term x) = runEval (runDiff @_ @w (noEnv x)) () \\ weightCon @w @(Vector Eval)
 >       go :: M.Show w => (DiffType w (w -> XOR)) -> w -> (w -> DiffType w w) -> (DiffType w (XOR -> M.Double)) -> (M.Double -> w -> w -> w) -> M.Int -> (w -> XOR) -> m XOR
 >       go xor weight reifyE lossE updateW i orig | i <= 2500 = do
 >         doIter i lossVal (M.show weight)
diff --git a/DeepDarkFantasy.cabal b/DeepDarkFantasy.cabal
--- a/DeepDarkFantasy.cabal
+++ b/DeepDarkFantasy.cabal
@@ -1,5 +1,5 @@
 name: DeepDarkFantasy
-version: 0.2017.8.4
+version: 0.2017.8.7
 cabal-version: 1.12
 build-type: Simple
 license: Apache
@@ -18,13 +18,12 @@
 source-repository head
   type: git
   location: https://github.com/ThoughtWorksInc/DeepDarkFantasy
-
+             
 library
   exposed-modules:
     DDF.Bimap
     DDF.Bool
     DDF.Char
-    DDF.Combine
     DDF.DBI
     DDF.Diff
     DDF.DiffWrapper
@@ -34,7 +33,6 @@
     DDF.Fix
     DDF.Float
     DDF.FreeVector
-    DDF.GDiff
     DDF.ImportMeta
     DDF.ImpW
     DDF.Int
@@ -49,11 +47,14 @@
     DDF.Meta.FreeVector
     DDF.Meta.VectorTF
     DDF.Option
+    DDF.PE
     DDF.Poly
     DDF.Prod
     DDF.Show
     DDF.Size
     DDF.Sum
+    DDF.Term
+    DDF.TermGen
     DDF.UInt
     DDF.UnHOAS
     DDF.Unit
@@ -64,7 +65,6 @@
     DDF.WithDiff
     DDF.Xor
     DDF.Y
-    DDF.PE
   build-depends:
     base >= 4.9.0.0 && <= 4.9.1.0,
     mtl -any,
@@ -72,8 +72,10 @@
     constraints -any,
     containers -any,
     bimap -any,
-    recursion-schemes -any
-  ghc-options: -Wall -Wno-type-defaults -Wno-missing-signatures -Wno-orphans -fwarn-tabs -ferror-spans
+    recursion-schemes -any,
+    constraint-unions -any,
+    template-haskell -any
+  ghc-options: -Wall -Wno-type-defaults -Wno-missing-signatures -Wno-orphans -fwarn-tabs -ferror-spans -Wno-partial-type-signatures
   if flag(WError)
     ghc-options: -Werror
   default-language: Haskell2010
diff --git a/test/TestPE.hs b/test/TestPE.hs
--- a/test/TestPE.hs
+++ b/test/TestPE.hs
@@ -17,7 +17,6 @@
 import DDF.Meta.Interpreter
 import Test.QuickCheck
 import DDF.Eval
-import DDF.Combine
 
 class TestEqual x where
   testEqual :: x -> x -> M.IO ()
