diff --git a/less-arbitrary.cabal b/less-arbitrary.cabal
--- a/less-arbitrary.cabal
+++ b/less-arbitrary.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.33.0.
+-- This file has been generated from package.yaml by hpack version 0.35.1.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: d30ca38bcbe9101a7c179c5cc3776be35b4afb646db121fc65bb6ed099cf261b
+-- hash: b0a355788abef7dbaf0d7e5cbcb66a193c430d26e49679c48cccc006d49399fc
 
 name:           less-arbitrary
-version:        0.1.7.0
+version:        0.1.8.0
 synopsis:       Linear time testing with variant of Arbitrary class that always terminates.
 description:    Ever found non-terminating Arbitrary instance?
                 Ever wondered what would be a runtime cost of particular Arbitrary instance?
@@ -54,7 +54,7 @@
       src
   build-depends:
       QuickCheck
-    , base >=4.5 && <=4.15
+    , base >=4.5 && <=4.17
     , containers
     , email-validate
     , generic-arbitrary
@@ -85,7 +85,7 @@
       test
   build-depends:
       QuickCheck
-    , base >=4.5 && <=4.15
+    , base >=4.5 && <=4.17
     , containers
     , email-validate
     , generic-arbitrary
diff --git a/src/Test/LessArbitrary.hs b/src/Test/LessArbitrary.hs
--- a/src/Test/LessArbitrary.hs
+++ b/src/Test/LessArbitrary.hs
@@ -1,21 +1,22 @@
 -- ~\~ language=Haskell filename=src/Test/LessArbitrary.hs
 -- ~\~ begin <<less-arbitrary.md|src/Test/LessArbitrary.hs>>[0]
-{-# language DefaultSignatures     #-}
-{-# language FlexibleInstances     #-}
-{-# language FlexibleContexts      #-}
+{-# language DefaultSignatures          #-}
+{-# language FlexibleInstances          #-}
+{-# language FlexibleContexts           #-}
 {-# language GeneralizedNewtypeDeriving #-}
-{-# language Rank2Types            #-}
-{-# language PolyKinds             #-}
-{-# language MultiParamTypeClasses #-}
-{-# language MultiWayIf            #-}
-{-# language ScopedTypeVariables   #-}
-{-# language TypeApplications      #-}
-{-# language TypeOperators         #-}
-{-# language TypeFamilies          #-}
-{-# language TupleSections         #-}
-{-# language UndecidableInstances  #-}
-{-# language AllowAmbiguousTypes   #-}
-{-# language DataKinds             #-}
+{-# language InstanceSigs               #-}
+{-# language Rank2Types                 #-}
+{-# language PolyKinds                  #-}
+{-# language MultiParamTypeClasses      #-}
+{-# language MultiWayIf                 #-}
+{-# language ScopedTypeVariables        #-}
+{-# language TypeApplications           #-}
+{-# language TypeOperators              #-}
+{-# language TypeFamilies               #-}
+{-# language TupleSections              #-}
+{-# language UndecidableInstances       #-}
+{-# language AllowAmbiguousTypes        #-}
+{-# language DataKinds                  #-}
 module Test.LessArbitrary(
     LessArbitrary(..)
   , oneof
@@ -34,74 +35,95 @@
   , elements
   , forAll
   , sizedCost
+  , StartingState(..)
   ) where
 
-import qualified Data.HashMap.Strict as Map
-import qualified Data.Set            as Set
-import qualified Data.Vector         as Vector
-import qualified Data.Text           as Text
-import Control.Monad(replicateM)
-import Data.Scientific
-import Data.Proxy
-import qualified Test.QuickCheck.Gen as QC
+import qualified Data.HashMap.Strict        as Map
+import qualified Data.Set                   as Set
+import qualified Data.Vector                as Vector
+import qualified Data.Text                  as Text
+import           Control.Monad (replicateM)
+import           Data.Scientific
+import           Data.Proxy
+import qualified Test.QuickCheck.Gen        as QC
 import qualified Control.Monad.State.Strict as State
-import Control.Monad.Trans.Class
-import System.Random(Random)
-import GHC.Generics as G
-import GHC.Generics as Generic
-import GHC.TypeLits
-import GHC.Stack
+import           Control.Arrow (first, second)
+import           Control.Monad.Trans.Class
+import           System.Random (Random)
+import           GHC.Generics    as G
+import           GHC.Generics    as Generic
+import           GHC.TypeLits
+import           GHC.Stack
 import qualified Test.QuickCheck as QC
-import Data.Hashable
+import           Data.Hashable
 
 import Test.LessArbitrary.Cost
 
+-- ~\~ begin <<less-arbitrary.md|starting-state>>[0]
+class StartingState s where
+  startingState :: s
+
+instance StartingState () where
+  startingState = ()
+-- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|costgen>>[0]
-newtype CostGen                               a =
+newtype CostGen s a =
         CostGen {
-          runCostGen :: State.StateT Cost QC.Gen a }
+          runCostGen :: State.StateT (Cost, s) QC.Gen a
+        }
   deriving (Functor, Applicative, Monad, State.MonadFix)
+
+instance State.MonadState        s  (CostGen s) where
+  state :: forall s a.
+           (s -> (a, s)) -> CostGen s a
+  state nestedMod = CostGen $ State.state mod
+    where
+      mod :: (Cost, s) -> (a, (Cost, s))
+      mod (aCost, aState) = (result, (aCost, newState))
+        where
+          (result, newState) = nestedMod aState
 -- ~\~ end
 
 -- Mark a costly constructor with this instead of `<$>`
-(<$$$>) :: (a -> b) -> CostGen a -> CostGen b
+(<$$$>) :: (a -> b) -> CostGen s a -> CostGen s b
 costlyConstructor <$$$> arg = do
   spend 1
   costlyConstructor <$> arg
 
 -- ~\~ begin <<less-arbitrary.md|spend>>[0]
-spend :: Cost -> CostGen ()
+spend :: Cost -> CostGen s ()
 spend c = do
-  CostGen $ State.modify (-c+)
+  CostGen $ State.modify (first (-c+))
   checkBudget
 -- ~\~ end
 
 -- ~\~ begin <<less-arbitrary.md|budget>>[0]
 ($$$?) :: HasCallStack
-       => CostGen a
-       -> CostGen a
-       -> CostGen a
+       => CostGen s a
+       -> CostGen s a
+       -> CostGen s a
 cheapVariants $$$? costlyVariants = do
-  budget <- CostGen State.get
+  budget <- fst <$> CostGen State.get
   if | budget > (0 :: Cost) -> costlyVariants
      | budget > -10000      -> cheapVariants
      | otherwise            -> error $
        "Recursive structure with no loop breaker."
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|budget>>[1]
-checkBudget :: HasCallStack => CostGen ()
+checkBudget :: HasCallStack => CostGen s ()
 checkBudget = do
-  budget <- CostGen State.get
+  budget <- fst <$> CostGen State.get
   if budget < -10000
     then error "Recursive structure with no loop breaker."
     else return ()
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|budget>>[2]
-currentBudget :: CostGen Cost
-currentBudget = CostGen State.get
+currentBudget :: CostGen s Cost
+currentBudget = fst <$> CostGen State.get
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|budget>>[3]
 -- unused: loop breaker message type name
+-- FIXME: use to make nicer error message
 type family ShowType k where
   ShowType (D1 ('MetaData name _ _ _) _) = name
   ShowType  other                        = "unknown type"
@@ -114,10 +136,17 @@
 -- ~\~ end
 
 
-withCost :: Int -> CostGen a -> QC.Gen a
-withCost cost gen = runCostGen gen
-  `State.evalStateT` Cost cost
+withCost :: forall        s a.
+            StartingState s
+         => Int
+         -> CostGen       s a
+         -> QC.Gen          a
+withCost cost gen = withCostAndState cost startingState gen
 
+withCostAndState :: Int -> s -> CostGen s a -> QC.Gen a
+withCostAndState cost state gen = runCostGen gen
+  `State.evalStateT` (Cost cost, state)
+
 -- ~\~ begin <<less-arbitrary.md|generic-instances>>[0]
 type family Min m n where
   Min m n = ChooseSmaller (CmpNat m n) m n
@@ -148,38 +177,38 @@
   Cheapness (C1 a other) = 1
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|generic-instances>>[2]
-instance GLessArbitrary           f
-      => GLessArbitrary (G.C1 c f) where
+instance GLessArbitrary s         f
+      => GLessArbitrary s (G.C1 c f) where
   gLessArbitrary = G.M1 <$> gLessArbitrary
   cheapest       = G.M1 <$> cheapest
 
-instance GLessArbitrary           f
-      => GLessArbitrary (G.S1 c f) where
+instance GLessArbitrary s         f
+      => GLessArbitrary s (G.S1 c f) where
   gLessArbitrary = G.M1 <$> gLessArbitrary
   cheapest       = G.M1 <$> cheapest
 -- ~\~ end
 
 -- ~\~ begin <<less-arbitrary.md|generic-less-arbitrary>>[0]
-genericLessArbitraryMonoid :: (Generic             a
-                              ,GLessArbitrary (Rep a)
-                              ,Monoid              a )
-                           =>  CostGen             a
+genericLessArbitraryMonoid :: (Generic               a
+                              ,GLessArbitrary s (Rep a)
+                              ,Monoid                a )
+                           =>  CostGen        s      a
 genericLessArbitraryMonoid  =
   pure mempty $$$? genericLessArbitrary
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|generic-less-arbitrary>>[1]
-class GLessArbitrary datatype where
-  gLessArbitrary :: CostGen (datatype p)
-  cheapest       :: CostGen (datatype p)
+class GLessArbitrary s datatype where
+  gLessArbitrary :: CostGen s (datatype p)
+  cheapest       :: CostGen s (datatype p)
 
-genericLessArbitrary :: (Generic             a
-                        ,GLessArbitrary (Rep a))
-                     =>  CostGen             a
+genericLessArbitrary :: (Generic               a
+                        ,GLessArbitrary s (Rep a))
+                     =>  CostGen        s      a
 genericLessArbitrary = G.to <$> gLessArbitrary
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|generic-less-arbitrary>>[2]
-instance GLessArbitrary       f
-      => GLessArbitrary (D1 m f) where 
+instance GLessArbitrary s       f
+      => GLessArbitrary s (D1 m f) where 
   gLessArbitrary = do
     spend 1
     M1 <$> (cheapest $$$? gLessArbitrary)
@@ -191,34 +220,34 @@
   SumLen  a          = 1
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|generic-less-arbitrary>>[4]
-instance GLessArbitrary G.U1 where
+instance GLessArbitrary s G.U1 where
   gLessArbitrary = pure G.U1
   cheapest       = pure G.U1
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|generic-less-arbitrary>>[5]
-instance (GLessArbitrary  a
-         ,GLessArbitrary          b)
-      =>  GLessArbitrary (a G.:*: b) where
+instance (GLessArbitrary  s  a
+         ,GLessArbitrary  s          b)
+      =>  GLessArbitrary  s (a G.:*: b) where
   gLessArbitrary = (G.:*:) <$> gLessArbitrary
                            <*> gLessArbitrary
   cheapest       = (G.:*:) <$> cheapest
                            <*> cheapest
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|generic-less-arbitrary>>[6]
-instance  LessArbitrary         c
-      => GLessArbitrary (G.K1 i c) where
+instance  LessArbitrary s         c
+      => GLessArbitrary s (G.K1 i c) where
   gLessArbitrary = G.K1 <$> lessArbitrary
   cheapest       = G.K1 <$> lessArbitrary
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|generic-less-arbitrary>>[7]
-instance (GLessArbitrary      a
-         ,GLessArbitrary                    b
+instance (GLessArbitrary s    a
+         ,GLessArbitrary s                  b
          ,KnownNat (SumLen    a)
          ,KnownNat (SumLen                  b)
          ,KnownNat (Cheapness a)
          ,KnownNat (Cheapness               b)
          )
-      => GLessArbitrary      (a Generic.:+: b) where
+      => GLessArbitrary  s   (a Generic.:+: b) where
   gLessArbitrary =
     frequency
       [ (lfreq, L1 <$> gLessArbitrary)
@@ -241,104 +270,116 @@
 -- ~\~ end
 
 -- ~\~ begin <<less-arbitrary.md|less-arbitrary-class>>[0]
-class LessArbitrary a where
-  lessArbitrary :: CostGen a
+class StartingState s
+   => LessArbitrary s a where
+  lessArbitrary :: CostGen s a
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|less-arbitrary-class>>[1]
-  default lessArbitrary :: (Generic             a
-                           ,GLessArbitrary (Rep a))
-                        =>  CostGen             a
+  default lessArbitrary :: (Generic               a
+                           ,GLessArbitrary s (Rep a))
+                        =>  CostGen        s      a
   lessArbitrary = genericLessArbitrary
 -- ~\~ end
 
-instance LessArbitrary Bool where
+instance StartingState s
+      => LessArbitrary s Bool where
   lessArbitrary = flatLessArbitrary
 
-instance LessArbitrary Int where
+instance StartingState s
+      => LessArbitrary s Int where
   lessArbitrary = flatLessArbitrary
 
-instance LessArbitrary Integer where
+instance StartingState s
+      => LessArbitrary s Integer where
   lessArbitrary = flatLessArbitrary
 
-instance LessArbitrary Double where
+instance StartingState s
+      => LessArbitrary s Double where
   lessArbitrary = flatLessArbitrary
 
-instance LessArbitrary Char where
+instance StartingState s
+      => LessArbitrary s Char where
   lessArbitrary = flatLessArbitrary
 
-instance (LessArbitrary k
-         ,LessArbitrary   v)
-      => LessArbitrary (k,v) where
+instance (LessArbitrary s  k
+         ,LessArbitrary s    v)
+      =>  LessArbitrary s (k,v) where
 
-instance (LessArbitrary          k
-         ,Ord                    k)
-      =>  LessArbitrary (Set.Set k) where
+instance (LessArbitrary s          k
+         ,Ord                      k)
+      =>  LessArbitrary s (Set.Set k) where
   lessArbitrary = Set.fromList <$> lessArbitrary
 
-instance (LessArbitrary              k
-         ,Eq                         k
-         ,Ord                        k
-         ,Hashable                   k 
-         ,LessArbitrary                v)
-      =>  LessArbitrary (Map.HashMap k v) where
+instance (LessArbitrary s              k
+         ,Eq                           k
+         ,Ord                          k
+         ,Hashable                     k 
+         ,LessArbitrary s                v)
+      =>  LessArbitrary s (Map.HashMap k v) where
   lessArbitrary =  Map.fromList
                <$> lessArbitrary
 
-instance LessArbitrary Scientific where
+instance StartingState s
+      => LessArbitrary  s Scientific where
   lessArbitrary =
     scientific <$> lessArbitrary
                <*> lessArbitrary
 
 -- ~\~ begin <<less-arbitrary.md|arbitrary-implementation>>[0]
-fasterArbitrary :: LessArbitrary a => QC.Gen a
-fasterArbitrary = sizedCost lessArbitrary
+fasterArbitrary :: forall        s a.
+                   LessArbitrary s a
+                => QC.Gen          a
+fasterArbitrary  = (sizedCost :: CostGen s a -> QC.Gen a) (lessArbitrary :: CostGen s a)
 
-sizedCost :: CostGen a -> QC.Gen a
+sizedCost :: LessArbitrary s a
+          => CostGen       s a
+          -> QC.Gen          a
 sizedCost gen = QC.sized (`withCost` gen)
 -- ~\~ end
 
 flatLessArbitrary :: QC.Arbitrary a
-              => CostGen a
+                  => CostGen    s a
 flatLessArbitrary  = CostGen $ lift QC.arbitrary
 
-instance LessArbitrary                a
-      => LessArbitrary (Vector.Vector a) where
+instance LessArbitrary s                a
+      => LessArbitrary s (Vector.Vector a) where
   lessArbitrary = Vector.fromList <$> lessArbitrary
 
 -- ~\~ begin <<less-arbitrary.md|lifting-arbitrary>>[0]
-instance LessArbitrary  a
-      => LessArbitrary [a] where
+instance LessArbitrary s  a
+      => LessArbitrary s [a] where
   lessArbitrary = pure [] $$$? do
     budget <- currentBudget
     len  <- choose (1,fromEnum budget)
     spend $ Cost len
     replicateM   len lessArbitrary
 
-instance QC.Testable          a
-      => QC.Testable (CostGen a) where
+instance (QC.Testable            a
+         ,LessArbitrary        s a)
+      =>  QC.Testable (CostGen s a) where
   property = QC.property
            . sizedCost
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|lifting-arbitrary>>[1]
-forAll :: CostGen a -> (a -> CostGen b) -> CostGen b
+forAll :: CostGen s a -> (a -> CostGen s b) -> CostGen s b
 forAll gen prop = gen >>= prop
 
 oneof   :: HasCallStack
-        => [CostGen a] -> CostGen a
+        => [CostGen s a] -> CostGen s a
 oneof [] = error
            "LessArbitrary.oneof used with empty list"
 oneof gs = choose (0,length gs - 1) >>= (gs !!)
 
-elements :: [a] -> CostGen a
+elements :: [a] -> CostGen s a
 elements gs = (gs!!) <$> choose (0,length gs - 1)
 
 choose      :: Random  a
             =>        (a, a)
-            -> CostGen a
+            -> CostGen s a
 choose (a,b) = CostGen $ lift $ QC.choose (a, b)
 
 -- | Choose but only up to the budget (for array and list sizes)
-budgetChoose :: CostGen Int
+budgetChoose :: CostGen s Int
 budgetChoose  = do
   Cost b <- currentBudget
   CostGen $ lift $ QC.choose (1, b)
@@ -354,7 +395,8 @@
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|lifting-arbitrary>>[2]
 frequency   :: HasCallStack
-            => [(Int, CostGen a)] -> CostGen a
+            => [(Int, CostGen s a)]
+            ->        CostGen s a
 frequency [] =
   error $ "LessArbitrary.frequency "
        ++ "used with empty list"
diff --git a/src/Test/LessArbitrary/Laws.hs b/src/Test/LessArbitrary/Laws.hs
--- a/src/Test/LessArbitrary/Laws.hs
+++ b/src/Test/LessArbitrary/Laws.hs
@@ -5,6 +5,7 @@
 {-# language Rank2Types            #-}
 {-# language MultiParamTypeClasses #-}
 {-# language ScopedTypeVariables   #-}
+{-# language TypeApplications      #-}
 {-# language TypeOperators         #-}
 {-# language UndecidableInstances  #-}
 {-# language AllowAmbiguousTypes   #-}
@@ -20,17 +21,21 @@
 import           Data.HashMap.Strict(HashMap)
 
 -- ~\~ begin <<less-arbitrary.md|less-arbitrary-laws>>[0]
-lessArbitraryLaws :: LessArbitrary a
-                  => (a -> Bool) -> Laws
+lessArbitraryLaws :: forall        s a.
+                     LessArbitrary s a
+                  =>                (a -> Bool)
+                  -> Laws
 lessArbitraryLaws cheapestPred =
     Laws "LessArbitrary"
          [("always selects cheapest",
            property $
-             prop_alwaysCheapest cheapestPred)]
+             (prop_alwaysCheapest @s @a) cheapestPred)]
 
-prop_alwaysCheapest :: LessArbitrary a
-                    => (a -> Bool) -> Gen Bool
+prop_alwaysCheapest :: forall s a.
+                       LessArbitrary s a
+                    =>                (a -> Bool)
+                    -> Gen                  Bool
 prop_alwaysCheapest cheapestPred =
-  cheapestPred <$> withCost 0 lessArbitrary
+  cheapestPred <$> (withCost @s @a) 0 lessArbitrary
 -- ~\~ end
 -- ~\~ end
diff --git a/test/less/LessArbitrary.hs b/test/less/LessArbitrary.hs
--- a/test/less/LessArbitrary.hs
+++ b/test/less/LessArbitrary.hs
@@ -2,23 +2,26 @@
 -- ~\~ begin <<less-arbitrary.md|test/less/LessArbitrary.hs>>[0]
 -- ~\~ begin <<less-arbitrary.md|test-file-header>>[0]
 {-# language FlexibleInstances     #-}
+{-# language InstanceSigs          #-}
 {-# language Rank2Types            #-}
 {-# language MultiParamTypeClasses #-}
 {-# language ScopedTypeVariables   #-}
+{-# language TypeApplications      #-}
 {-# language TypeOperators         #-}
 {-# language UndecidableInstances  #-}
 {-# language AllowAmbiguousTypes   #-}
 {-# language DeriveGeneric         #-}
 module Main where
 
-import Data.Proxy
-import Test.QuickCheck
+import           Data.Proxy
+import           Test.QuickCheck
+import qualified Test.QuickCheck.Gen as QC
 import qualified GHC.Generics as Generic
-import Test.QuickCheck.Classes
+import           Test.QuickCheck.Classes
 
-import Test.LessArbitrary
-import Test.Arbitrary.Laws
-import Test.LessArbitrary.Laws
+import           Test.LessArbitrary
+import           Test.Arbitrary.Laws
+import           Test.LessArbitrary.Laws
 
 -- ~\~ begin <<less-arbitrary.md|tree-type>>[0]
 data Tree        a =
@@ -28,12 +31,16 @@
 -- ~\~ end
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|test-less-arbitrary-version>>[0]
-instance LessArbitrary       a
-      => LessArbitrary (Tree a) where
+instance (Arbitrary             a
+         ,LessArbitrary s       a)
+      =>  LessArbitrary s (Tree a) where
+  lessArbitrary = genericLessArbitrary
 
-instance LessArbitrary   a
-      => Arbitrary (Tree a) where
-  arbitrary = fasterArbitrary
+instance (LessArbitrary () (Tree a)
+         ,Arbitrary              a)
+      => Arbitrary         (Tree a) where
+  arbitrary = fasterArbitrary @() @(Tree a)
+  shrink    = recursivelyShrink
 -- ~\~ end
 
 -- ~\~ begin <<less-arbitrary.md|test-file-laws>>[0]
@@ -48,7 +55,7 @@
 -- ~\~ end
 -- ~\~ begin <<less-arbitrary.md|less-arbitrary-check>>[0]
 otherLaws :: [Laws]
-otherLaws = [lessArbitraryLaws isLeaf]
+otherLaws = [lessArbitraryLaws @() isLeaf]
   where
     isLeaf :: Tree Int -> Bool
     isLeaf (Leaf   _) = True
