diff --git a/cartel.cabal b/cartel.cabal
--- a/cartel.cabal
+++ b/cartel.cabal
@@ -3,16 +3,16 @@
 -- http://www.github.com/massysett/cartel
 --
 -- Script name used to generate: GenCartelCabal.hs
--- Generated on: 2015-09-09 21:53:21.77097 EDT
--- Cartel library version: 0.14.2.8
+-- Generated on: 2016-01-30 07:32:28.40375 EST
+-- Cartel library version: 0.16.0.0
 
 name: cartel
-version: 0.14.2.8
-cabal-version: >= 1.18
+version: 0.16.0.0
+cabal-version: >= 1.10
 license: BSD3
 license-file: LICENSE
 build-type: Simple
-copyright: Copyright 2014-2015 Omari Norman
+copyright: Copyright 2014-2016 Omari Norman
 author: Omari Norman
 maintainer: omari@smileystation.com
 stability: Experimental
@@ -46,7 +46,7 @@
   hs-source-dirs:
     lib
   build-depends:
-      base >= 4.7.0.0 && < 5
+      base >= 4.8.0.0 && < 5
     , directory >= 1.1.0.2
     , filepath >= 1.3.0.0
     , time >= 1.4
@@ -61,6 +61,14 @@
     buildable: True
     other-modules:
       Cartel.Generators
+      Cartel
+      Cartel.Ast
+      Cartel.Betsy
+      Cartel.Betsy.Internal
+      Cartel.GenCartelCabal
+      Cartel.Render
+      Cartel.Types
+      Cartel.Version
     hs-source-dirs:
       tests
     build-depends:
@@ -75,7 +83,7 @@
     hs-source-dirs:
       lib
     build-depends:
-        base >= 4.7.0.0 && < 5
+        base >= 4.8.0.0 && < 5
       , directory >= 1.1.0.2
       , filepath >= 1.3.0.0
       , time >= 1.4
@@ -89,6 +97,14 @@
   default-language: Haskell2010
   other-modules:
     Cartel.Generators
+    Cartel
+    Cartel.Ast
+    Cartel.Betsy
+    Cartel.Betsy.Internal
+    Cartel.GenCartelCabal
+    Cartel.Render
+    Cartel.Types
+    Cartel.Version
   other-extensions:
     TemplateHaskell
   hs-source-dirs:
@@ -105,7 +121,7 @@
   hs-source-dirs:
     lib
   build-depends:
-      base >= 4.7.0.0 && < 5
+      base >= 4.8.0.0 && < 5
     , directory >= 1.1.0.2
     , filepath >= 1.3.0.0
     , time >= 1.4
diff --git a/lib/Cartel.hs b/lib/Cartel.hs
--- a/lib/Cartel.hs
+++ b/lib/Cartel.hs
@@ -34,6 +34,32 @@
 -- errors that you have to fix by changing the program that generates
 -- the file.
 --
+-- I highly recommend that you use Cartel with @stack@, a Haskell
+-- build tool.  Stack is available at
+--
+-- <https://github.com/commercialhaskell/stack>
+--
+-- By using @stack@ as a script interpreter, you can help ensure that
+-- your Cartel script runs well into the future.  This is described at
+--
+-- <http://docs.haskellstack.org/en/stable/GUIDE.html#ghc-runghc>
+--
+-- In particular, to have a Cartel script that uses @stack@, you do
+-- something like this in your Cartel script:
+--
+-- @
+-- #!\/usr/\bin\/env\/stack
+-- -- stack --resolver lts-5.0 --install-ghc runghc --package cartel
+-- module Main where
+-- import qualified Cartel as C
+-- -- etc...
+-- @
+--
+-- However, if you have a @stack.yaml@ file in the same directory as
+-- your Cabal file, @stack@ will get confused.  To work around this,
+-- temporarily rename your @stack.yaml@ file while you use your Cartel
+-- script (you can easily write a script to automate this).
+--
 -- Everything you usually need is in this module.  Other Cartel
 -- modules contain implementation details.  /See first/ the
 -- 'NonEmptyString' type synonym, which has important details on how
@@ -48,7 +74,6 @@
   ( -- * Basic types and classes
     Word
   , NonEmptyString
-  , Blank(..)
   , Version
 
   -- * Sections
@@ -102,6 +127,7 @@
   , nextBreaking
   , nextMajor
   , exactly
+  , atLeast
   , unconstrained
 
   -- * Build information
@@ -241,10 +267,8 @@
 import Cartel.Render
 import Cartel.Types
 import qualified Cartel.Version
-import Control.Applicative
 import Data.List (intersperse)
 import Data.Time
-import Data.Word
 import System.Environment (getProgName)
 import System.Exit (exitFailure, exitSuccess)
 import qualified System.IO as IO
diff --git a/lib/Cartel/Ast.hs b/lib/Cartel/Ast.hs
--- a/lib/Cartel/Ast.hs
+++ b/lib/Cartel/Ast.hs
@@ -20,7 +20,6 @@
 
 import qualified Data.Char as C
 import qualified System.FilePath as P
-import Data.Word
 import System.FilePath
 import Data.List (sortBy, intersperse)
 import Data.Monoid
@@ -29,19 +28,6 @@
 import Cartel.Types
 import Cartel.Betsy
 
--- * Basic types
-
--- * Blank
-
--- | Typeclass for things that can be blank.  More specifically,
--- @blank a@ results in an item that, when rendered in a Cabal file,
--- is the null string.  'blank' can be useful to indicate that you
--- have no options, and you can also use it in combination with record
--- syntax when you want to specify just a few options.
-
-class Blank a where
-  blank :: a
-
 -- * Repositories
 
 -- | What kind of VCS repository is this?
@@ -87,7 +73,17 @@
 archVcs = ArchVcs
 monotone = Monotone
 
--- | A single @repository@ section.
+-- | Takes the last non-Nothing value, or returns Nothing if both
+-- values are Nothing.
+lastJust :: Maybe a -> Maybe a -> Maybe a
+lastJust a b = case (a, b) of
+  (Nothing, Nothing) -> Nothing
+  (Just x, Nothing) -> Just x
+  (Nothing, Just y) -> Just y
+  (Just _, Just y) -> Just y
+
+-- | A single @repository@ section.  This is an instance of 'Monoid',
+-- so to get a blank 'Repository' section, use 'mempty'.
 data Repository = Repository
   { repoVcs :: Maybe Vcs
   -- ^ What kind of 'Vcs' this is.  This is required.
@@ -111,8 +107,11 @@
   -- ^ The repository subdirectory.
   } deriving (Eq, Ord, Show)
 
-instance Blank Repository where
-  blank = Repository Nothing Nothing "" "" "" ""
+instance Monoid Repository where
+  mempty = Repository Nothing Nothing "" "" "" ""
+  mappend (Repository a0 a1 a2 a3 a4 a5) (Repository b0 b1 b2 b3 b4 b5)
+    = Repository (lastJust a0 b0) (lastJust a1 b1) (a2 <> b2) (a3 <> b3)
+        (a4 <> b4) (a5 <> b5)
 
 -- | Creates a 'Section' that is a 'Repository' for a Github head.
 -- For example, for Cartel, use @githubHead \"massysett\" \"cartel\"@.
@@ -123,10 +122,10 @@
   -- ^ The Github project name within the account
   -> Section
 githubHead acct proj
-  = SecRepo $ blank { repoVcs = Just Git
-                    , repoKind = Just Head
-                    , repoLocation = loc
-                    }
+  = SecRepo $ mempty { repoVcs = Just Git
+                     , repoKind = Just Head
+                     , repoLocation = loc
+                     }
   where
     loc = "https://github.com/" ++ acct ++ "/" ++ proj ++ ".git"
 
@@ -340,6 +339,13 @@
 exactly :: NonEmptyString -> Version -> Package
 exactly n v = Package n (eq v)
 
+-- | Depends on this version, or any greater version.
+--
+-- > atLeast "base" [4,5,0,0] ==> version >= 4.5.0.0
+
+atLeast :: NonEmptyString -> Version -> Package
+atLeast n v = Package n (gtEq v)
+
 -- | Allows any version of a package.
 
 unconstrained
@@ -602,6 +608,11 @@
   -- ^ An executable can contain zero or more 'ExecutableField's.
   } deriving (Eq, Ord, Show)
 
+instance Monoid Executable where
+  mempty = Executable "" []
+  mappend (Executable a0 a1) (Executable b0 b1)
+    = Executable (a0 <> b0) (a1 <> b1)
+
 -- | Builds a 'Section' for executable files.
 executable
   :: NonEmptyString
@@ -666,6 +677,11 @@
   -- ^ Zero or more 'TestSuiteField's.
   } deriving (Eq, Ord, Show)
 
+instance Monoid TestSuite where
+  mempty = TestSuite "" []
+  mappend (TestSuite a0 a1) (TestSuite b0 b1)
+    = TestSuite (a0 <> b0) (a1 <> b1)
+
 -- | Builds a 'Section' for test suites.
 testSuite
   :: NonEmptyString
@@ -703,6 +719,11 @@
   -- ^ Zero or more benchmark fields.
   } deriving (Eq, Ord, Show)
 
+instance Monoid Benchmark where
+  mempty = Benchmark "" []
+  mappend (Benchmark a0 a1) (Benchmark b0 b1)
+    = Benchmark (a0 <> b0) (a1 <> b1)
+
 -- | Builds a 'Section' for benchmarks.
 benchmark
   :: NonEmptyString
@@ -1163,11 +1184,27 @@
 jhc = JHC
 lhc = LHC
 
--- | Global package properties.
+-- | Global package properties.  Is an instance of 'Monoid' so to get
+-- a blank 'Properties' use 'mempty', for example:
+--
+-- @
+-- properties = mempty
+--  { name = "mypackage"
+--  , version = [0,1]
+--  , cabalVersion = Just (1,10)
+--  , buildType = Just simple
+--  -- etc.  Fields you don't supply will be blank.
+--  }
+-- @
+
 data Properties = Properties
   { name :: String
   , version :: Version
   , cabalVersion :: Maybe (Word, Word)
+  -- ^ The version of the Cabal specification to use.  As of
+  -- 2016-01-30 I can find no documentation on what these different
+  -- versions are.  @cabal init@ of the @cabal-install@ program
+  -- version 1.22.6.0 is using @1.10@ as the default value here.
   , buildType :: Maybe BuildType
   , license :: Maybe License
   , licenseFile :: String
@@ -1192,8 +1229,8 @@
   , extraTmpFiles :: [NonEmptyString]
   } deriving (Eq, Ord, Show)
 
-instance Blank Properties where
-  blank = Properties
+instance Monoid Properties where
+  mempty = Properties
     { name = ""
     , version = []
     , cabalVersion = Nothing
@@ -1219,9 +1256,36 @@
     , extraTmpFiles = []
     }
 
+  mappend a b = Properties
+    { name = name a <> name b
+    , version = version a <> version b
+    , cabalVersion = lastJust (cabalVersion a) (cabalVersion b)
+    , buildType = lastJust (buildType a) (buildType b)
+    , license = lastJust (license a) (license b)
+    , licenseFile = licenseFile a <> licenseFile b
+    , licenseFiles = licenseFiles a <> licenseFiles b
+    , copyright = copyright a <> copyright b
+    , author = author a <> author b
+    , maintainer = maintainer a <> maintainer b
+    , stability = stability a <> stability b
+    , homepage = homepage a <> homepage b
+    , bugReports = bugReports a <> bugReports b
+    , packageUrl = packageUrl a <> packageUrl b
+    , synopsis = synopsis a <> synopsis b
+    , description = description a <> description b
+    , category = category a <> category b
+    , testedWith = testedWith a <> testedWith b
+    , dataFiles = dataFiles a <> dataFiles b
+    , dataDir = dataDir a <> dataDir b
+    , extraSourceFiles = extraSourceFiles a <> extraSourceFiles b
+    , extraDocFiles = extraDocFiles a <> extraDocFiles b
+    , extraTmpFiles = extraTmpFiles a <> extraTmpFiles b
+    }
+
 -- * Cabal
 
--- | Represents an entire Cabal file.
+-- | Represents an entire Cabal file.  Is an instance of 'Monoid' so
+-- to get a blank 'Cabal' use 'mempty'.
 data Cabal = Cabal
   { properties :: Properties
   , library :: [LibraryField]
@@ -1229,5 +1293,7 @@
   , flags :: [Flag]
   } deriving (Eq, Ord, Show)
 
-instance Blank Cabal where
-  blank = Cabal blank [] [] []
+instance Monoid Cabal where
+  mempty = Cabal mempty [] [] []
+  mappend (Cabal a0 a1 a2 a3) (Cabal b0 b1 b2 b3)
+    = Cabal (a0 <> b0) (a1 <> b1) (a2 <> b2) (a3 <> b3)
diff --git a/lib/Cartel/Betsy/Internal.hs b/lib/Cartel/Betsy/Internal.hs
--- a/lib/Cartel/Betsy/Internal.hs
+++ b/lib/Cartel/Betsy/Internal.hs
@@ -6,7 +6,6 @@
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Cartel.Types
-import Control.Applicative
 
 -- | Errors that may result from running a 'Betsy' computation.
 data Error
diff --git a/lib/Cartel/GenCartelCabal.hs b/lib/Cartel/GenCartelCabal.hs
--- a/lib/Cartel/GenCartelCabal.hs
+++ b/lib/Cartel/GenCartelCabal.hs
@@ -10,11 +10,8 @@
 
 -- Dependencies
 
-atLeast :: NonEmptyString -> [Word] -> Package
-atLeast name ver = package name (gtEq ver)
-
 base :: Package
-base = closedOpen "base" [4,7,0,0] [5]
+base = closedOpen "base" [4,8,0,0] [5]
 
 directory :: Package
 directory = atLeast "directory" [1,1,0,2]
@@ -77,7 +74,7 @@
               })
   testMods <- modules "tests"
   return
-    ( blank
+    ( mempty
       { name = "cartel"
         , version = Cartel.Version.version
         , buildType = Just simple
@@ -94,10 +91,10 @@
             ]
         , license = Just bsd3
         , licenseFile = "LICENSE"
-        , copyright = "Copyright 2014-2015 Omari Norman"
+        , copyright = "Copyright 2014-2016 Omari Norman"
         , author = "Omari Norman"
         , stability = "Experimental"
-        , cabalVersion = Just (1,18)
+        , cabalVersion = Just (1,10)
         , homepage = "http://www.github.com/massysett/cartel"
         , bugReports = "http://www.github.com/massysett/cartel/issues"
         , extraSourceFiles = ["README.md"]
@@ -108,7 +105,8 @@
       , executable "cartel-visual-test"
         [ condBlock (flag flagVisual)
           ( buildable True
-          , otherModules testMods : testOptions
+          , otherModules (testMods ++ libModules)
+            : testOptions
           )
           [ buildable False
           ]
@@ -117,7 +115,7 @@
         ]
       , testSuite "cartel-properties"
         $ haskell2010 
-        : otherModules testMods 
+        : otherModules (testMods ++ libModules)
         : otherExtensions ["TemplateHaskell"]
         : testOptions
         ++ exitcodeFields "cartel-properties.hs"
diff --git a/lib/Cartel/Render.hs b/lib/Cartel/Render.hs
--- a/lib/Cartel/Render.hs
+++ b/lib/Cartel/Render.hs
@@ -5,11 +5,9 @@
 
 import Cartel.Ast
 import Cartel.Betsy
-import Control.Applicative
 import Control.Monad.Trans.Reader
 import Data.Char (isLetter, isDigit)
 import Data.List (intersperse)
-import Data.Word
 
 -- | Separate two strings with a space, but only if both strings are
 -- not empty.
diff --git a/lib/Cartel/Version.hs b/lib/Cartel/Version.hs
--- a/lib/Cartel/Version.hs
+++ b/lib/Cartel/Version.hs
@@ -8,7 +8,5 @@
 
 module Cartel.Version where
 
-import Data.Word
-
 version :: [Word]
-version = [0,14,2,8]
+version = [0,16,0,0]
diff --git a/tests/Cartel/Generators.hs b/tests/Cartel/Generators.hs
--- a/tests/Cartel/Generators.hs
+++ b/tests/Cartel/Generators.hs
@@ -5,7 +5,6 @@
 import Cartel.Betsy
 import Cartel.Ast
 import Cartel.Render
-import Control.Applicative
 import Control.Monad.Trans.State
 import Control.Monad.Trans.Class
 import System.Random (StdGen, random, randomR, Random(..), mkStdGen)
diff --git a/tests/cartel-visual-test.hs b/tests/cartel-visual-test.hs
--- a/tests/cartel-visual-test.hs
+++ b/tests/cartel-visual-test.hs
@@ -2,7 +2,6 @@
 -- for details on what arguments to use.
 module Main where
 
-import Data.Word
 import Cartel.Generators
 import System.Environment
 import Data.Either
