diff --git a/DDF/Poly.lhs b/DDF/Poly.lhs
deleted file mode 100644
--- a/DDF/Poly.lhs
+++ /dev/null
@@ -1,114 +0,0 @@
-> {-# LANGUAGE
->   NoImplicitPrelude,
->   MultiParamTypeClasses,
->   RankNTypes,
->   ScopedTypeVariables,
->   FlexibleInstances,
->   FlexibleContexts,
->   UndecidableInstances,
->   IncoherentInstances,
->   PolyKinds,
->   LambdaCase,
->   NoMonomorphismRestriction,
->   TypeFamilies,
->   LiberalTypeSynonyms,
->   EmptyCase
-> #-}
-
-> module DDF.Poly where
-> import Control.Monad (when)
-> import DDF.Util
-> import DDF.Lang
-> import DDF.Show
-> import DDF.Diff ()
-> import qualified Control.Monad as M
-> import Prelude (Integer)
-> import qualified Prelude as M
-> import qualified DDF.Meta.Dual as M
-> import DDF.Eval
-
-Importing files and opening language extension...
-So, our goal is to find x, where x * x + 2 * x + 3 = 27.
-To do so, we try to minimize their difference squared (l2 norm).
-
-> poly :: forall repr h. Lang repr => repr h (M.Double -> M.Double)
-> poly = lam $ \x -> plus2 (mult2 x x) (plus2 (mult2 (double 2.0) x) (double 3.0))
-
-poly x = x * x + (2 * x + 3)
-
-> l2 = lam $ \x -> mult2 (minus2 x (double 27)) (minus2 x (double 27))
-
-l2 x = (x - 27) * (x - 27)
-l2 measure how far is the input from 27
-
-> comp = com2 l2 poly
-
-By composing the two, we can measure how far is x * x + 2 * x + 3 from 27.
-We want to minimize this distance.
-
-Now write a generic function that calculate x and return it.
-
-> solve :: forall m. M.Monad m => (AST -> m ()) -> (Integer -> M.Double -> m ()) -> m M.Double
-> solve doAST doIter = do
-
-Let's begin by trying to print poly
-
->   doAST $ runShow poly vars 0
->   go 0 0
->   where
-
-The main loop. i is step and w is weight (our current estimate of x).
-We start by assuming x = 0 is the solution,
-and minimize (comp x) by taking derivative of x, and decrease it whenever it is positive (and vice versa).
-
->     go :: Integer -> M.Double -> m M.Double
->     go i w | i < 200 = do
->       doIter i w
->       go (1 + i) $ w - 0.001 * M.dualDiff (runEval (runDiff $ noEnv comp) () $ M.Dual (w, 1))
-
-noEnv comp assume the term (which is a De Brujin Index term) need no environment (is free)
-and it is a finally tagless term, with WDiff interpreter being implicitly applied,
-which return another finally tagless term, but taking derivative of x.
-it is then applied to Eval interpreter (which eval it in the meta language, haskell).
-similar to runWDiff, we use runEval to take out the term from a newtype
-now we apply the environment (remember it has no environment? so just stick a unit)
-and a pair, the zeroth being x, the first being derivative of x, which is 1.
-the whole computation return a pair of (x * x + (2 * x + 3) - 27)^2, and it's derivative.
-we modify w using the derivative.
-
->     go _ w = M.return w
-
-By running the program, you shall see
-(\a -> (plus (mult a a) (plus (mult 2.0 a) 3.0)))
-since we pretty print poly
-followed by something like
-0.0
-9.6e-2
-0.43573084645674215
-1.1890033104995505
-2.498644212525056
-3.652210805402036
-3.9662181049468925
-3.9981203814732154
-3.9999338218043157
-3.999998509763363
-3.9999999785234146
-3.9999999998019136
-3.9999999999988307
-3.9999999999999956
-3.999999999999999
-which mean we found 4 as a soultion.
-plugging it back to the equation, we can verify that (4 * 4) + 2 * 4 + 3 is indeed 27!
-
-Now the main function:
-
-> main :: M.IO ()
-> main = do
->   d <- solve print printSquare
->   M.putStrLn $ "x is: " ++ (show d)
->   M.return ()
->   where
->     printSquare i x = when (isSquare i) (print x)
-
-the only thing worth noting is that we print the weight in increasing interval,
-so initially more weight is printed
diff --git a/DDF/Sam/Poly.lhs b/DDF/Sam/Poly.lhs
new file mode 100644
--- /dev/null
+++ b/DDF/Sam/Poly.lhs
@@ -0,0 +1,114 @@
+> {-# LANGUAGE
+>   NoImplicitPrelude,
+>   MultiParamTypeClasses,
+>   RankNTypes,
+>   ScopedTypeVariables,
+>   FlexibleInstances,
+>   FlexibleContexts,
+>   UndecidableInstances,
+>   IncoherentInstances,
+>   PolyKinds,
+>   LambdaCase,
+>   NoMonomorphismRestriction,
+>   TypeFamilies,
+>   LiberalTypeSynonyms,
+>   EmptyCase
+> #-}
+
+> module DDF.Sam.Poly where
+> import Control.Monad (when)
+> import DDF.Util
+> import DDF.Lang
+> import DDF.Show
+> import DDF.Diff ()
+> import qualified Control.Monad as M
+> import Prelude (Integer)
+> import qualified Prelude as M
+> import qualified DDF.Meta.Dual as M
+> import DDF.Eval
+
+Importing files and opening language extension...
+So, our goal is to find x, where x * x + 2 * x + 3 = 27.
+To do so, we try to minimize their difference squared (l2 norm).
+
+> poly :: forall repr h. Lang repr => repr h (M.Double -> M.Double)
+> poly = lam $ \x -> plus2 (mult2 x x) (plus2 (mult2 (double 2.0) x) (double 3.0))
+
+poly x = x * x + (2 * x + 3)
+
+> l2 = lam $ \x -> mult2 (minus2 x (double 27)) (minus2 x (double 27))
+
+l2 x = (x - 27) * (x - 27)
+l2 measure how far is the input from 27
+
+> comp = com2 l2 poly
+
+By composing the two, we can measure how far is x * x + 2 * x + 3 from 27.
+We want to minimize this distance.
+
+Now write a generic function that calculate x and return it.
+
+> solve :: forall m. M.Monad m => (AST -> m ()) -> (Integer -> M.Double -> m ()) -> m M.Double
+> solve doAST doIter = do
+
+Let's begin by trying to print poly
+
+>   doAST $ runShow poly vars 0
+>   go 0 0
+>   where
+
+The main loop. i is step and w is weight (our current estimate of x).
+We start by assuming x = 0 is the solution,
+and minimize (comp x) by taking derivative of x, and decrease it whenever it is positive (and vice versa).
+
+>     go :: Integer -> M.Double -> m M.Double
+>     go i w | i < 200 = do
+>       doIter i w
+>       go (1 + i) $ w - 0.001 * M.dualDiff (runEval (runDiff $ noEnv comp) () $ M.Dual (w, 1))
+
+noEnv comp assume the term (which is a De Brujin Index term) need no environment (is free)
+and it is a finally tagless term, with WDiff interpreter being implicitly applied,
+which return another finally tagless term, but taking derivative of x.
+it is then applied to Eval interpreter (which eval it in the meta language, haskell).
+similar to runWDiff, we use runEval to take out the term from a newtype
+now we apply the environment (remember it has no environment? so just stick a unit)
+and a pair, the zeroth being x, the first being derivative of x, which is 1.
+the whole computation return a pair of (x * x + (2 * x + 3) - 27)^2, and it's derivative.
+we modify w using the derivative.
+
+>     go _ w = M.return w
+
+By running the program, you shall see
+(\a -> (plus (mult a a) (plus (mult 2.0 a) 3.0)))
+since we pretty print poly
+followed by something like
+0.0
+9.6e-2
+0.43573084645674215
+1.1890033104995505
+2.498644212525056
+3.652210805402036
+3.9662181049468925
+3.9981203814732154
+3.9999338218043157
+3.999998509763363
+3.9999999785234146
+3.9999999998019136
+3.9999999999988307
+3.9999999999999956
+3.999999999999999
+which mean we found 4 as a soultion.
+plugging it back to the equation, we can verify that (4 * 4) + 2 * 4 + 3 is indeed 27!
+
+Now the main function:
+
+> main :: M.IO ()
+> main = do
+>   d <- solve print printSquare
+>   M.putStrLn $ "x is: " ++ (show d)
+>   M.return ()
+>   where
+>     printSquare i x = when (isSquare i) (print x)
+
+the only thing worth noting is that we print the weight in increasing interval,
+so initially more weight is printed
diff --git a/DDF/Sam/Xor.lhs b/DDF/Sam/Xor.lhs
new file mode 100644
--- /dev/null
+++ b/DDF/Sam/Xor.lhs
@@ -0,0 +1,138 @@
+> {-# 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.
+
+> module DDF.Sam.Xor where
+> import qualified Prelude as M
+> import System.Random
+> import Control.Monad (when)
+> import Data.Constraint
+> import DDF.Util
+> import DDF.Lang
+> import DDF.Show
+> import DDF.Eval ()
+> import DDF.Term
+> import DDF.ImpW
+> import DDF.WithDiff
+> import DDF.Eval
+> import qualified DDF.Meta.Dual as M
+
+Recall in poly, we constructed a function Double -> Double,
+with argument being the weight, and do gradient descend to found a solution.
+
+However, most of the time, there wil be more than one weight (or no weight at all).
+Also, when we are composing a Neural Network to approximate a value, we dont really care how much weight it use.
+So, we use existential type to hide the actual weight.
+
+data ImpW repr h x = forall w. Weight w => ImpW (repr h (w -> x))
+
+ImpW stands for implicit weights.
+The existential w is weight, and a Neural Network of type x is just a function from w to x!
+We require that the weight can be constructed randomly, so we have random initialization.
+Weight also form a Vector so we can combine weights (update it), scale it (to control the learning rate).
+
+Let's start by constructing a weight.
+
+> doubleWeight :: Lang repr => ImpW repr h M.Double
+> doubleWeight = ImpW id
+
+Note that we are just manipulating AST.
+If you wanna do weight sharing, you need to use let(in DDF) yourself.
+
+Obviously, we just need to take the implicit argument.
+
+We have the weight, now we need the activation function, sigmoid.
+
+> sigmoid = lam $ \x -> recip1 (plus2 doubleOne (doubleExp1 (invert1 x)))
+> sigmoid1 = app sigmoid
+
+With weight and sigmoid we can construct a neuron of type ((M.Double, M.Double) -> M.Double)
+The weight should be a pair of M.Double, each as a scale on the actual input, with a bias.
+We then add the two scaled input, with the bias, and pass them into sigmoid.
+
+> scaleAdd :: Lang repr => ImpW repr h ((M.Double, M.Double) -> M.Double)
+> scaleAdd = ImpW $ lam2 $ \w p -> plus2 (mult2 (zro1 w) (zro1 p)) (plus2 (fst1 w) (fst1 p))
+
+> withBias :: Lang repr => ImpW repr h (M.Double -> M.Double)
+> withBias = ImpW $ plus
+
+> neuron :: Lang repr => ImpW repr h ((M.Double, M.Double) -> M.Double)
+> neuron = com2 (com2 sigmoid withBias) scaleAdd
+> neuron1 = app neuron
+
+Now, the hidden layer of type (M.Double, M.Double) -> ((M.Double, M.Double), (M.Double, M.Double))
+
+> hidden = lam $ \p -> mkProd2 (mkProd2 (neuron1 p) (neuron1 p)) (mkProd2 (neuron1 p) (neuron1 p))
+
+And finally, the whole NN:
+
+> type XOR = (M.Double, M.Double) -> M.Double
+> xorNet :: Lang repr => ImpW repr h XOR
+> xorNet = neuron `com2` (bimap2 scaleAdd scaleAdd) `com2` hidden
+
+But before we can train it, we need to define the dataset and the loss function.
+
+> l2 :: Lang repr => repr h (M.Double -> M.Double -> M.Double)
+> l2 = lam2 $ \l r -> (mult2 (minus2 l r) (minus2 l r))
+> l22 = app2 l2
+
+> eval :: Lang repr => repr h (XOR -> ((M.Double, M.Double), M.Double) -> M.Double)
+> eval = lam2 $ \xor p -> l22 (app xor (zro1 p)) (fst1 p)
+
+> dataset :: Lang repr => repr h [((M.Double, M.Double), M.Double)]
+> dataset = cons2 (build 0 0 0) (cons2 (build 0 1 1) (cons2 (build 1 0 1) (cons2 (build 1 1 0) nil)))
+>   where build l r ret = mkProd2 (mkProd2 (double l) (double r)) (double ret)
+
+However, unlike Poly, there are more than one datapoint, so we need to use a list, and map xor onto it.
+
+> loss :: Lang repr => repr h (XOR -> M.Double)
+> loss = lam $ \xor -> y2 (lam $ \self -> listMatch2 doubleZero (lam2 $ \x xs -> plus2 x (app self xs))) (map2 (app eval xor) dataset)
+
+Now we are good to implement the train function!
+
+> 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 ((Term net) :: Weight w => Term Lang () (w -> XOR)) -> do
+>     doAST $ runShow net vars 0
+
+printing weights. now you will see a list of gibberish
+
+>     let initWeight :: w = M.fst $ ((randomR (randRange (-0.01, 0.01)) \\ weightCon @w @Random) \\ weightCon @w @RandRange) rand
+
+Getting random weights...
+
+>     (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 :: 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)
+>         go xor (updateW 0.3 weight lossDiff) reifyE lossE updateW (1 + i) orig
+>           where
+>             M.Dual (lossVal, lossDiff) = lossE $ xor (reifyE weight)
+>       go _ weight _ _ _ _ orig = M.return $ orig weight
+
+> main :: M.IO ()
+> main = do
+>   g <- getStdGen
+>   xorTrained <- findXor g print (\i d w -> when (isSquare i) $ do
+>     print d
+>     M.putStrLn w
+>     M.putStrLn "")
+>   let doXor :: M.Double -> M.Double -> M.IO ()
+>       doXor l r = M.putStrLn $ M.show l ++ " xor " ++ M.show r ++ " is " ++ (M.show $ xorTrained (l, r))
+>   doXor 0 0
+>   doXor 0 1
+>   doXor 1 0
+>   doXor 1 1
+>   M.return ()
diff --git a/DDF/Show.hs b/DDF/Show.hs
--- a/DDF/Show.hs
+++ b/DDF/Show.hs
@@ -16,6 +16,8 @@
 lamAST str (Lam st l t) = Lam str (st:l) t
 lamAST str r = Lam str [] r
 
+vars = [pre : suf | suf <- "":M.map show [0..], pre <- ['a'..'z']]
+
 instance M.Show AST where
   show (Leaf f) = f
   show (App f x l) = "(" ++ f ++ " " ++ show x ++ M.concatMap ((" " ++) . show) l ++ ")"
diff --git a/DDF/Util.hs b/DDF/Util.hs
--- a/DDF/Util.hs
+++ b/DDF/Util.hs
@@ -5,8 +5,6 @@
 import System.Random
 import GHC.Float
 
-vars = [pre : suf | suf <- "":map show [0..], pre <- ['a'..'z']]
-
 isSquare n = sq * sq == n
   where sq = floor $ sqrt (fromIntegral n::Double)
 
diff --git a/DDF/Xor.lhs b/DDF/Xor.lhs
deleted file mode 100644
--- a/DDF/Xor.lhs
+++ /dev/null
@@ -1,138 +0,0 @@
-> {-# 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.
-
-> module DDF.Xor where
-> import qualified Prelude as M
-> import System.Random
-> import Control.Monad (when)
-> import Data.Constraint
-> import DDF.Util
-> import DDF.Lang
-> import DDF.Show
-> import DDF.Eval ()
-> import DDF.Term
-> import DDF.ImpW
-> import DDF.WithDiff
-> import DDF.Eval
-> import qualified DDF.Meta.Dual as M
-
-Recall in poly, we constructed a function Double -> Double,
-with argument being the weight, and do gradient descend to found a solution.
-
-However, most of the time, there wil be more than one weight (or no weight at all).
-Also, when we are composing a Neural Network to approximate a value, we dont really care how much weight it use.
-So, we use existential type to hide the actual weight.
-
-data ImpW repr h x = forall w. Weight w => ImpW (repr h (w -> x))
-
-ImpW stands for implicit weights.
-The existential w is weight, and a Neural Network of type x is just a function from w to x!
-We require that the weight can be constructed randomly, so we have random initialization.
-Weight also form a Vector so we can combine weights (update it), scale it (to control the learning rate).
-
-Let's start by constructing a weight.
-
-> doubleWeight :: Lang repr => ImpW repr h M.Double
-> doubleWeight = ImpW id
-
-Note that we are just manipulating AST.
-If you wanna do weight sharing, you need to use let(in DDF) yourself.
-
-Obviously, we just need to take the implicit argument.
-
-We have the weight, now we need the activation function, sigmoid.
-
-> sigmoid = lam $ \x -> recip1 (plus2 doubleOne (doubleExp1 (invert1 x)))
-> sigmoid1 = app sigmoid
-
-With weight and sigmoid we can construct a neuron of type ((M.Double, M.Double) -> M.Double)
-The weight should be a pair of M.Double, each as a scale on the actual input, with a bias.
-We then add the two scaled input, with the bias, and pass them into sigmoid.
-
-> scaleAdd :: Lang repr => ImpW repr h ((M.Double, M.Double) -> M.Double)
-> scaleAdd = ImpW $ lam2 $ \w p -> plus2 (mult2 (zro1 w) (zro1 p)) (plus2 (fst1 w) (fst1 p))
-
-> withBias :: Lang repr => ImpW repr h (M.Double -> M.Double)
-> withBias = ImpW $ plus
-
-> neuron :: Lang repr => ImpW repr h ((M.Double, M.Double) -> M.Double)
-> neuron = com2 (com2 sigmoid withBias) scaleAdd
-> neuron1 = app neuron
-
-Now, the hidden layer of type (M.Double, M.Double) -> ((M.Double, M.Double), (M.Double, M.Double))
-
-> hidden = lam $ \p -> mkProd2 (mkProd2 (neuron1 p) (neuron1 p)) (mkProd2 (neuron1 p) (neuron1 p))
-
-And finally, the whole NN:
-
-> type XOR = (M.Double, M.Double) -> M.Double
-> xorNet :: Lang repr => ImpW repr h XOR
-> xorNet = neuron `com2` (bimap2 scaleAdd scaleAdd) `com2` hidden
-
-But before we can train it, we need to define the dataset and the loss function.
-
-> l2 :: Lang repr => repr h (M.Double -> M.Double -> M.Double)
-> l2 = lam2 $ \l r -> (mult2 (minus2 l r) (minus2 l r))
-> l22 = app2 l2
-
-> eval :: Lang repr => repr h (XOR -> ((M.Double, M.Double), M.Double) -> M.Double)
-> eval = lam2 $ \xor p -> l22 (app xor (zro1 p)) (fst1 p)
-
-> dataset :: Lang repr => repr h [((M.Double, M.Double), M.Double)]
-> dataset = cons2 (build 0 0 0) (cons2 (build 0 1 1) (cons2 (build 1 0 1) (cons2 (build 1 1 0) nil)))
->   where build l r ret = mkProd2 (mkProd2 (double l) (double r)) (double ret)
-
-However, unlike Poly, there are more than one datapoint, so we need to use a list, and map xor onto it.
-
-> loss :: Lang repr => repr h (XOR -> M.Double)
-> loss = lam $ \xor -> y2 (lam $ \self -> listMatch2 doubleZero (lam2 $ \x xs -> plus2 x (app self xs))) (map2 (app eval xor) dataset)
-
-Now we are good to implement the train function!
-
-> 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 ((Term net) :: Weight w => Term Lang () (w -> XOR)) -> do
->     doAST $ runShow net vars 0
-
-printing weights. now you will see a list of gibberish
-
->     let initWeight :: w = M.fst $ ((randomR (randRange (-0.01, 0.01)) \\ weightCon @w @Random) \\ weightCon @w @RandRange) rand
-
-Getting random weights...
-
->     (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 :: 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)
->         go xor (updateW 0.3 weight lossDiff) reifyE lossE updateW (1 + i) orig
->           where
->             M.Dual (lossVal, lossDiff) = lossE $ xor (reifyE weight)
->       go _ weight _ _ _ _ orig = M.return $ orig weight
-
-> main :: M.IO ()
-> main = do
->   g <- getStdGen
->   xorTrained <- findXor g print (\i d w -> when (isSquare i) $ do
->     print d
->     M.putStrLn w
->     M.putStrLn "")
->   let doXor :: M.Double -> M.Double -> M.IO ()
->       doXor l r = M.putStrLn $ M.show l ++ " xor " ++ M.show r ++ " is " ++ (M.show $ xorTrained (l, r))
->   doXor 0 0
->   doXor 0 1
->   doXor 1 0
->   doXor 1 1
->   M.return ()
diff --git a/DeepDarkFantasy.cabal b/DeepDarkFantasy.cabal
--- a/DeepDarkFantasy.cabal
+++ b/DeepDarkFantasy.cabal
@@ -1,5 +1,5 @@
 name: DeepDarkFantasy
-version: 0.2017.8.8
+version: 0.2017.8.9
 cabal-version: 1.12
 build-type: Simple
 license: Apache
@@ -20,50 +20,49 @@
   location: https://github.com/ThoughtWorksInc/DeepDarkFantasy
              
 library
-  exposed-modules:
-    DDF.Bimap
-    DDF.Bool
-    DDF.Char
-    DDF.DBI
-    DDF.Diff
-    DDF.DiffWrapper
-    DDF.Double
-    DDF.Dual
-    DDF.Eval
-    DDF.Fix
-    DDF.Float
-    DDF.FreeVector
-    DDF.ImportMeta
-    DDF.ImpW
-    DDF.Int
-    DDF.IO
-    DDF.Lang
-    DDF.List
-    DDF.Map
-    DDF.Meta.Diff
-    DDF.Meta.DiffWrapper
-    DDF.Meta.Dual
-    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
-    DDF.UnLiftEnv
-    DDF.Util
-    DDF.Vector
-    DDF.VectorTF
-    DDF.WithDiff
-    DDF.Xor
-    DDF.Y
+  exposed-modules: DDF.Bimap
+                   DDF.Bool
+                   DDF.Char
+                   DDF.DBI
+                   DDF.Diff
+                   DDF.DiffWrapper
+                   DDF.Double
+                   DDF.Dual
+                   DDF.Eval
+                   DDF.Fix
+                   DDF.Float
+                   DDF.FreeVector
+                   DDF.ImportMeta
+                   DDF.ImpW
+                   DDF.Int
+                   DDF.IO
+                   DDF.Lang
+                   DDF.List
+                   DDF.Map
+                   DDF.Meta.Diff
+                   DDF.Meta.DiffWrapper
+                   DDF.Meta.Dual
+                   DDF.Meta.FreeVector
+                   DDF.Meta.VectorTF
+                   DDF.Option
+                   DDF.PE
+                   DDF.Prod
+                   DDF.Sam.Poly
+                   DDF.Sam.Xor
+                   DDF.Show
+                   DDF.Size
+                   DDF.Sum
+                   DDF.Term
+                   DDF.TermGen
+                   DDF.UInt
+                   DDF.UnHOAS
+                   DDF.Unit
+                   DDF.UnLiftEnv
+                   DDF.Util
+                   DDF.Vector
+                   DDF.VectorTF
+                   DDF.WithDiff
+                   DDF.Y
   build-depends:
     base >= 4.9.0.0 && <= 4.9.1.0,
     mtl -any,
@@ -78,7 +77,7 @@
     ghc-options: -Werror
   default-language: Haskell2010
 
-Test-Suite TestPoly
+test-Suite TestPoly
   type: exitcode-stdio-1.0
   default-language: Haskell2010
   hs-source-dirs: test
@@ -88,9 +87,9 @@
     mtl -any,
     random -any,
     constraints -any,
-    DeepDarkFantasy
+    DeepDarkFantasy -any
 
-Test-Suite TestXor
+test-Suite TestXor
   type: exitcode-stdio-1.0
   default-language: Haskell2010
   hs-source-dirs: test
@@ -100,9 +99,9 @@
     mtl -any,
     random -any,
     constraints -any,
-    DeepDarkFantasy
+    DeepDarkFantasy -any
 
-Test-Suite TestPE
+test-Suite TestPE
   type: exitcode-stdio-1.0
   default-language: Haskell2010
   hs-source-dirs: test
@@ -112,5 +111,5 @@
     mtl -any,
     random -any,
     constraints -any,
-    QuickCheck,
-    DeepDarkFantasy
+    QuickCheck -any,
+    DeepDarkFantasy -any
diff --git a/test/TestPoly.hs b/test/TestPoly.hs
--- a/test/TestPoly.hs
+++ b/test/TestPoly.hs
@@ -1,6 +1,6 @@
 module Main where
 
-import DDF.Poly hiding (main)
+import DDF.Sam.Poly hiding (main)
 import Control.Monad
 import System.Exit (exitFailure)
 
diff --git a/test/TestXor.hs b/test/TestXor.hs
--- a/test/TestXor.hs
+++ b/test/TestXor.hs
@@ -1,6 +1,6 @@
 module Main where
 
-import DDF.Xor hiding (main)
+import DDF.Sam.Xor hiding (main)
 import Control.Monad
 import System.Exit (exitFailure)
 import System.Random
