diff --git a/HCL.cabal b/HCL.cabal
--- a/HCL.cabal
+++ b/HCL.cabal
@@ -1,5 +1,5 @@
 Name:           HCL
-Version:        1.5.1
+Version:        1.6
 License:        BSD3
 Author:         Justin Bailey
 Homepage:       http://github.com/m4dc4p/hcl/tree/master
@@ -14,8 +14,7 @@
   Dates, or other structured values), build lists of values, and use simple
   menus. It is not intended to build complex interfaces with full cursor
   control. It is oriented towards line-based interfaces.
-cabal-version: >= 1.6
-
+cabal-version: >= 1.8
 Data-files: hangman/2of12.txt
 
 Library
@@ -24,6 +23,23 @@
   Hs-Source-Dirs: src
 
 Executable hangman
-  Build-Depends:  base >= 4.7 && < 5, QuickCheck == 2.*, mtl, random, containers
+  Build-Depends:  base >= 4.7 && < 5, QuickCheck == 2.*, mtl, random, containers, HCL
   Main-Is:        Hangman.hs
-  Hs-Source-Dirs: hangman, src
+  Hs-Source-Dirs: hangman
+  other-modules:  Paths_HCL
+
+test-suite HCL-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  hs-source-dirs: test
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  Build-Depends:  base >= 4.7 && < 5, QuickCheck == 2.*, mtl, random, containers, HCL, HUnit
+  other-modules:
+    Spec.AndReq
+    Spec.Constructors
+    Spec.Common
+    Spec.NotReq
+    Spec.OrReq
+    Spec.ReqIf
+    Spec.ReqLift
+    Spec.ReqLift2
diff --git a/src/System/Console/HCL.hs b/src/System/Console/HCL.hs
--- a/src/System/Console/HCL.hs
+++ b/src/System/Console/HCL.hs
@@ -4,7 +4,7 @@
 
 /Requests/
 
-The central concept of the library is the 'Request' type, which embodies an interactive request for data. When requesting data, there is always the possibility of failure. That is, the user may enter a value that doesn't parse, or may want to quit the process. For this reason, the value stored by a request is @"IO" ("Maybe a")@, which shows there may not always be a value available. 'Request' is a monad, and when a request fails, no subsequent requests are asked. Instead, the whole request chain is abandoned.
+The central concept of the library is the 'Request' type, which embodies an interactive request for data. When requesting data, there is always the possibility of failure. That is, the user may enter a value that doesn't parse, or may want to quit the process. For this reason, the value stored by a request is @"IO" ("Maybe" a)@, which shows there may not always be a value available. 'Request' is a monad, and when a request fails, no subsequent requests are asked. Instead, the whole request chain is abandoned.
 
 The function 'reqResp' gives the most basic request possible, which is for a string. From this, other requests can be built. The library provides several:
 
@@ -14,7 +14,7 @@
 
  * 'reqChar' - Requests a single character (without waiting for the user to press enter)
 
- * 'reqPassword' - Like "reqResp", but doesn't echo the user's input to the console.
+ * 'reqPassword' - Like 'reqResp', but doesn't echo the user's input to the console.
 
  * 'reqRead' - Requests "Read"-able values.
 
@@ -305,7 +305,8 @@
 import System.IO.Unsafe (unsafePerformIO)
 import System.Random
 import Data.Maybe (isNothing, isJust)
-import Control.Monad (when)
+import Control.Applicative (Alternative (..))
+import Control.Monad (when, MonadPlus)
 import Control.Monad.Trans 
 
 {- |
@@ -332,21 +333,21 @@
 runRequest (Request r) = r
 
 {- |
-Because we have defined @Request@ as @Applicative@,
-we must also define it as @Functor@. -}
+Because we have defined @'Request'@ as @"Applicative"@,
+we must also define it as @"Functor"@. -}
 instance Functor Request where
   fmap = reqLift
 
 {- |
-Because we have defined @Request@ as @Monad@,
-we must also define it as @Applicative@. -}
+Because we have defined @'Request'@ as @"Monad"@,
+we must also define it as @"Applicative"@. -}
 instance Applicative Request where
   pure = makeReq
   f <*> x = f `andMaybe` \f' ->
     fmap f' x
 
 {- |
-Request behavior as a @Monad@ covers failure - when
+'Request' behavior as a @"Monad"@ covers failure - when
 a request results in @Nothing@, all bind
 operations fail afterwards. Thus, when one request fails,
 all subsequent requests automatically fail. -}
@@ -355,6 +356,22 @@
   fail _ = reqFail
 
 {- |
+Because we have defined @'Request'@ as @"MonadPlus"@, we must also
+define it as @"Alternative"@. -}
+instance Alternative Request where
+  empty = reqFail
+  x <|> y = Request $ do
+    maybeVal <- runRequest x
+    case maybeVal of
+      Nothing  -> runRequest y
+      Just val -> return $ Just val
+
+{- |
+'Request' behaviour as a @"MonadPlus"@ allows for successive fallback
+requests to be used on failure. -}
+instance MonadPlus Request
+
+{- |
 Takes a value and makes it into a request. Should
 not be an @IO (Maybe a)@ type value, unless
 multiply nested values is desired. -}
@@ -628,7 +645,8 @@
       Nothing -> return $ Just def
       v -> return v
 
--- Ask a request forever -- until failure. 
+{- |
+Ask a request forever -- until failure. -}
 reqForever :: Request a -- ^ Request to ask forever.
               -> Request a -- ^ Result.
 reqForever req =
@@ -727,10 +745,10 @@
       Left _ -> cont
       Right val -> return val
 
-{-
-Indicates if the request failed or succceeded. If @Left ()@ is
-returned, the request failed. If @Right v@ is returned, the request
-produce a value. Though the value returned is itself a request, it
+{- |
+Indicates if the request failed or succceeded. If @"Left" ()@ is
+returned, the request failed. If @"Right" v@ is returned, the request
+produced a value. Though the value returned is itself a request, it
 will always be valid. -}
 reqWhich :: Request a -- ^ Request to evaluate.
             -> Request (Either () a) -- ^ Result.
@@ -802,7 +820,8 @@
   in
     prompt msgWithDefault (reqDefault req def)
 
--- ^ Deprecated name for prompt1.
+{- |
+Deprecated name for 'prompt1'. -}
 promptWithDefault :: (Show a) => String -> Request a -> a -> Request a 
 promptWithDefault = prompt1
 
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,28 @@
+module Main where
+
+import Control.Monad
+import System.Exit
+import Test.HUnit
+
+import qualified Spec.AndReq as AndReq
+import qualified Spec.Constructors as Constructors
+import qualified Spec.NotReq as NotReq
+import qualified Spec.OrReq as OrReq
+import qualified Spec.ReqIf as ReqIf
+import qualified Spec.ReqLift as ReqLift
+import qualified Spec.ReqLift2 as ReqLift2
+
+main = do
+  counts <- runTestTT tests
+  when (failures counts > 0 || errors counts > 0)
+    exitFailure
+
+tests = TestList
+  [ Constructors.tests
+  , AndReq.tests
+  , OrReq.tests
+  , NotReq.tests
+  , ReqIf.tests
+  , ReqLift.tests
+  , ReqLift2.tests
+  ]
diff --git a/test/Spec/AndReq.hs b/test/Spec/AndReq.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/AndReq.hs
@@ -0,0 +1,23 @@
+module Spec.AndReq (tests) where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+import Spec.Common
+
+tests = TestLabel "andReq" $ TestList $ map test'
+  [ ( Nothing,    Nothing,    Nothing    )
+  , ( Just False, Nothing,    Just False )
+  , ( Just True,  Nothing,    Nothing    )
+  , ( Nothing,    Just True,  Nothing    )
+  , ( Just False, Just False, Just False )
+  , ( Just False, Just True,  Just False )
+  , ( Just True,  Just False, Just False )
+  , ( Just True,  Just True,  Just True  )
+  ]
+
+test' (x, y, expect) = let label = show x ++ " andReq " ++ show y
+  in TestLabel label $ TestCase $ do
+    val <- runRequest $ req x `andReq` req y
+    assertEqual "" val expect
diff --git a/test/Spec/Common.hs b/test/Spec/Common.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/Common.hs
@@ -0,0 +1,9 @@
+module Spec.Common where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+req x = case x of
+  Just x  -> makeReq x
+  Nothing -> reqFail
diff --git a/test/Spec/Constructors.hs b/test/Spec/Constructors.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/Constructors.hs
@@ -0,0 +1,17 @@
+module Spec.Constructors (tests) where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+tests = TestLabel "constructors" $ TestList [makeReqTests, reqFailTest]
+
+makeReqTests = TestLabel "makeReq" $ TestList $ map test' [ True, False ]
+
+test' x = TestLabel (show x) $ TestCase $ do
+  val <- runRequest $ makeReq x
+  assertEqual "" (Just x) val
+
+reqFailTest = TestLabel "reqFail" $ TestCase $ do
+  val <- runRequest (reqFail :: Request ())
+  assertEqual "" Nothing val
diff --git a/test/Spec/NotReq.hs b/test/Spec/NotReq.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/NotReq.hs
@@ -0,0 +1,18 @@
+module Spec.NotReq (tests) where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+import Spec.Common
+
+tests = TestLabel "notReq" $ TestList $ map test'
+  [ ( Nothing,    Nothing    )
+  , ( Just False, Just True  )
+  , ( Just True,  Just False )
+  ]
+
+test' (x, expect) = let label = "notReq " ++ show x in
+  TestLabel label $ TestCase $ do
+    val <- runRequest $ notReq $ req x
+    assertEqual "" expect val
diff --git a/test/Spec/OrReq.hs b/test/Spec/OrReq.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/OrReq.hs
@@ -0,0 +1,23 @@
+module Spec.OrReq (tests) where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+import Spec.Common
+
+tests = TestLabel "orReq" $ TestList $ map test'
+  [ ( Nothing,    Nothing,    Nothing    )
+  , ( Just True,  Nothing,    Just True  )
+  , ( Just False, Nothing,    Nothing    )
+  , ( Nothing,    Just True,  Nothing    )
+  , ( Just False, Just False, Just False )
+  , ( Just False, Just True,  Just True  )
+  , ( Just True,  Just False, Just True  )
+  , ( Just True,  Just True,  Just True  )
+  ]
+
+test' (x, y, expect) = let label = show x ++ " orReq " ++ show y
+  in TestLabel label $ TestCase $ do
+    val <- runRequest $ req x `orReq` req y
+    assertEqual "" val expect
diff --git a/test/Spec/ReqIf.hs b/test/Spec/ReqIf.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/ReqIf.hs
@@ -0,0 +1,18 @@
+module Spec.ReqIf (tests) where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+import Spec.Common
+
+tests = TestLabel "reqIf" $ TestList $ map test'
+  [ ( Nothing,    Nothing  )
+  , ( Just True,  Just 'a' )
+  , ( Just False, Just 'b' )
+  ]
+
+test' (x, expect) = let label = "reqIf " ++ show x in
+  TestLabel label $ TestCase $ do
+    val <- runRequest $ reqIf (req x) (return 'a') (return 'b')
+    assertEqual "" expect val
diff --git a/test/Spec/ReqLift.hs b/test/Spec/ReqLift.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/ReqLift.hs
@@ -0,0 +1,16 @@
+module Spec.ReqLift (tests) where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+import Spec.Common
+
+tests = TestLabel "reqLift" $ TestList $ map test'
+  [ ( Nothing, Nothing )
+  , ( Just 1,  Just 2  )
+  ]
+
+test' (x, expect) = TestLabel (show x) $ TestCase $ do
+  val <- runRequest $ reqLift succ $ req x
+  assertEqual "" expect val
diff --git a/test/Spec/ReqLift2.hs b/test/Spec/ReqLift2.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/ReqLift2.hs
@@ -0,0 +1,19 @@
+module Spec.ReqLift2 (tests) where
+
+import Test.HUnit
+
+import System.Console.HCL
+
+import Spec.Common
+
+tests = TestLabel "reqLift2" $ TestList $ map test'
+  [ ( Nothing, Nothing, Nothing )
+  , ( Just 1,  Nothing, Nothing )
+  , ( Nothing, Just 1,  Nothing )
+  , ( Just 1,  Just 1,  Just 2  )
+  ]
+
+test' (x, y, expect) = let label = show x ++ " + " ++ show y in
+  TestLabel label $ TestCase $ do
+    val <- runRequest $ reqLift2 (+) (req x) (req y)
+    assertEqual "" expect val
