diff --git a/exe/Example.hs b/exe/Example.hs
--- a/exe/Example.hs
+++ b/exe/Example.hs
@@ -1,15 +1,17 @@
 {-# LANGUAGE
     DataKinds
   , DeriveGeneric
+  , FlexibleContexts
   , OverloadedLabels
   , OverloadedStrings
   , TypeApplications
   , TypeOperators
 #-}
 
-module Main (main) where
+module Main (main, main2) where
 
-import Control.Monad.Base (liftBase)
+import Control.Monad (void)
+import Control.Monad.Base (liftBase, MonadBase)
 import Data.Int (Int32)
 import Data.Monoid ((<>))
 import Data.Text (Text)
@@ -86,6 +88,17 @@
   , User "Carole" (Just "carole@hotmail.com")
   ]
 
+session :: (MonadBase IO pq, MonadPQ Schema pq) => pq ()
+session = do
+  liftBase $ Char8.putStrLn "manipulating"
+  idResults <- traversePrepared insertUser (Only . userName <$> users)
+  ids <- traverse (fmap fromOnly . getRow (RowNumber 0)) idResults
+  traversePrepared_ insertEmail (zip (ids :: [Int32]) (userEmail <$> users))
+  liftBase $ Char8.putStrLn "querying"
+  usersResult <- runQuery getUsers
+  usersRows <- getRows usersResult
+  liftBase $ print (usersRows :: [User])
+
 main :: IO ()
 main = do
   Char8.putStrLn "squeal"
@@ -95,15 +108,14 @@
   connection0 <- connectdb connectionString
   Char8.putStrLn "setting up schema"
   connection1 <- execPQ (define setup) connection0
-  connection2 <- flip execPQ connection1 $ do
-    liftBase $ Char8.putStrLn "manipulating"
-    idResults <- traversePrepared insertUser (Only . userName <$> users)
-    ids <- traverse (fmap fromOnly . getRow (RowNumber 0)) idResults
-    traversePrepared_ insertEmail (zip (ids :: [Int32]) (userEmail <$> users))
-    liftBase $ Char8.putStrLn "querying"
-    usersResult <- runQuery getUsers
-    usersRows <- getRows usersResult
-    liftBase $ print (usersRows :: [User])
+  connection2 <- execPQ session connection1
   Char8.putStrLn "tearing down schema"
   connection3 <- execPQ (define teardown) connection2
   finish connection3
+
+main2 :: IO ()
+main2 = void $
+  withConnection "host=localhost port=5432 dbname=exampledb" . runPQ $
+    define setup
+    & pqThen session
+    & thenDefine teardown
diff --git a/squeal-postgresql.cabal b/squeal-postgresql.cabal
--- a/squeal-postgresql.cabal
+++ b/squeal-postgresql.cabal
@@ -1,5 +1,5 @@
 name: squeal-postgresql
-version: 0.1.0.0
+version: 0.1.1.0
 synopsis: Squeal PostgreSQL Library
 description: Squeal is a type-safe embedding of PostgreSQL in Haskell
 homepage: https://github.com/morphismtech/squeal
diff --git a/src/Squeal/PostgreSQL.hs b/src/Squeal/PostgreSQL.hs
--- a/src/Squeal/PostgreSQL.hs
+++ b/src/Squeal/PostgreSQL.hs
@@ -147,23 +147,25 @@
 -- Now we can put together all the pieces into a program. The program
 -- connects to the database, sets up the schema, inserts the user data
 -- (using prepared statements as an optimization), queries the user
--- data and prints it out and finally closes the connection. Since the
--- `Connection` tracks the schema of the database, we get a new one
--- when we execute our statements.
+-- data and prints it out and finally closes the connection. We can thread
+-- the changing schema information through by using the indexed `PQ` monad
+-- transformer and when the schema doesn't change we can use `Monad` and
+-- `MonadPQ` functionality.
 -- 
 -- > main :: IO ()
--- > main = do
--- >   connection0 <- connectdb "host=localhost port=5432 dbname=exampledb"
--- >   connection1 <- execPQ (define setup) connection0
--- >   connection2 <- flip execPQ connection1 $ do
--- >     idResults <- traversePrepared insertUser (Only . userName <$> users)
--- >     ids <- traverse (fmap fromOnly . getRow (RowNumber 0)) idResults
--- >     traversePrepared_ insertEmail (zip (ids :: [Int32]) (userEmail <$> users))
--- >     usersResult <- runQuery getUsers
--- >     usersRows <- getRows usersResult
--- >     liftBase $ print (usersRows :: [User])
--- >   connection3 <- execPQ (define teardown) connection2
--- >   finish connection3
+-- > main = void $
+-- >   withConnection "host=localhost port=5432 dbname=exampledb" . runPQ $
+-- >     define setup
+-- >     & pqThen session
+-- >     & thenDefine teardown
+-- >   where
+-- >     session = do
+-- >       idResults <- traversePrepared insertUser (Only . userName <$> users)
+-- >       ids <- traverse (fmap fromOnly . getRow (RowNumber 0)) idResults
+-- >       traversePrepared_ insertEmail (zip (ids :: [Int32]) (userEmail <$> users))
+-- >       usersResult <- runQuery getUsers
+-- >       usersRows <- getRows usersResult
+-- >       liftBase $ print (usersRows :: [User])
 
 module Squeal.PostgreSQL
   ( module Squeal.PostgreSQL.Binary
diff --git a/src/Squeal/PostgreSQL/Definition.hs b/src/Squeal/PostgreSQL/Definition.hs
--- a/src/Squeal/PostgreSQL/Definition.hs
+++ b/src/Squeal/PostgreSQL/Definition.hs
@@ -569,5 +569,5 @@
 -- in renderDefinition definition
 -- :}
 -- "ALTER TABLE tab ALTER COLUMN col TYPE numeric NOT NULL;"
-alterType :: TypeExpression ty -> AlterColumn ty0 ty1
+alterType :: TypeExpression ty -> AlterColumn ty0 ty
 alterType ty = UnsafeAlterColumn $ "TYPE" <+> renderTypeExpression ty
diff --git a/src/Squeal/PostgreSQL/PQ.hs b/src/Squeal/PostgreSQL/PQ.hs
--- a/src/Squeal/PostgreSQL/PQ.hs
+++ b/src/Squeal/PostgreSQL/PQ.hs
@@ -141,13 +141,14 @@
 
 -- | Do `connectdb` and `finish` before and after a computation.
 withConnection
-  :: forall schema io x
+  :: forall schema0 schema1 io x
    . MonadBaseControl IO io
   => ByteString
-  -> (Connection schema -> io x)
+  -> (Connection schema0 -> io (x, Connection schema1))
   -> io x
-withConnection connString = bracket (connectdb connString) finish
-
+withConnection connString action = do
+  (x, _conn) <- bracket (connectdb connString) finish action
+  return x
 
 -- | We keep track of the schema via an Atkey indexed state monad transformer,
 -- `PQ`.
