diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,10 @@
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,14 @@
+#!/usr/bin/runhaskell 
+> module Main where
+> import Distribution.Simple
+> import Distribution.PackageDescription(PackageDescription)
+> import Distribution.Simple.LocalBuildInfo(LocalBuildInfo)
+> import System.Cmd(system)
+> import Distribution.Simple.LocalBuildInfo
+>
+> main :: IO ()
+> main = defaultMainWithHooks hooks
+>   where hooks = simpleUserHooks { runTests = runspecs }
+>
+> runspecs :: Args -> Bool -> PackageDescription -> LocalBuildInfo -> IO ()
+> runspecs _ _ _ lbi = system "runhaskell ./Specs.hs" >> return ()
diff --git a/Specs.hs b/Specs.hs
new file mode 100644
--- /dev/null
+++ b/Specs.hs
@@ -0,0 +1,186 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Specs
+-- Copyright   :  (c) Trystan Spangler 2011
+-- License     :  modified BSD
+--
+-- Maintainer  : trystan.s@comcast.net
+-- Stability   : experimental
+-- Portability : portable
+--
+-- |
+--
+-----------------------------------------------------------------------------
+
+module Specs where
+
+import Test.Hspec.Internal
+import Test.Hspec.QuickCheck
+import Test.Hspec.HUnit ()
+import System.IO
+import System.Environment
+import Control.Monad (liftM)
+import qualified Test.HUnit as HUnit
+
+main :: IO ()
+main = do
+  ar <- getArgs
+  case ar of
+    ["README"] -> withFile "README" WriteMode (\ h -> hPutStrLn h preable >> hHspec h specs)
+    [filename] -> withFile filename WriteMode (\ h -> hHspec h specs)
+    _          -> hspec specs
+
+preable :: String
+preable = unlines [
+    "hspec aims to be a simple, extendable, and useful tool for Behavior Driven Development in Haskell.", "",
+    "",
+    "Step 1, write your specs",
+    "> specs = describe \"myabs\" [",
+    ">   it \"returns the original number when given a positive input\"",
+    ">     (myabs 1 == 1),",
+    "> ",
+    ">   it \"returns a positive number when given a negative input\"",
+    ">     (myabs (-1) == 1),",
+    "> ",
+    ">   it \"returns zero when given zero\"",
+    ">     (myabs 0 == 0)",
+    ">   ]",
+    "",
+    "Step 2, write your dummy function",
+    "> myabs n = undefined",
+    "",
+    "Step 3, watch them fail",
+    "> hspec specs",
+    "myabs",
+    " x returns the original number when given a positive input (Prelude.undefined)",
+    " x returns a positive number when given a negative input (Prelude.undefined)",
+    " x returns zero when given zero (Prelude.undefined)",
+    "",
+    "Finished in 0.0002 seconds",
+    "",
+    "3 examples, 3 failures",
+    "",
+    "Step 4, implement your requirements",
+    "> myabs n = if n < 0 then negate n else n", "",
+    "Step 5, watch them pass",
+    "> hspec specs",
+    "myabs",
+    " - returns the original number when given a positive input",
+    " - returns a positive number when given a negative input",
+    " - returns zero when given zero",
+    "",
+    "Finished in 0.0000 seconds",
+    "",
+    "3 examples, 0 failures",
+    "",
+    "",
+    "",
+    "",
+    "Here's the report of hspec's specs:" ]
+
+specs :: IO [Spec]
+specs = let spec = Spec "Example" "example"
+            testSpecs = [spec Success, spec (Fail ""), spec (Pending "")]
+        in liftM concat $ sequence [
+
+  describe "describe" [
+    it "takes a description of what the requirements are for"
+        ((=="Example") . name . head $ testSpecs),
+
+    it "groups requirements for what's being described"
+        (all ((=="Example").name) testSpecs)
+  ],
+  describe "it" [
+    it "takes a description of the requirement"
+        (requirement (Spec "Example" "whatever" Success) == "whatever" ),
+
+    it "takes an example of the requirement"
+        (result (spec Success) == Success),
+
+    it "can use a Bool, HUnit Test, QuickCheck property, or \"pending\" as an example"
+        (True),
+
+    it "will treat exceptions as failures"
+        (HUnit.TestCase $ do
+          innerSpecs <- describe "" [ it "exceptions" (True && undefined)]
+          let found = pureHspec innerSpecs !! 2
+          HUnit.assertEqual (unlines $ pureHspec innerSpecs) " x exceptions (Prelude.undefined)" found),
+
+    it "allows failed examples to have details"
+        (const True (Fail "details"))
+  ],
+  describe "Bool example" [
+    it "is just an expression that evaluates to a Bool"
+        (True)
+  ],
+  describe "HUnit example" [
+    it "is specified with the HUnit \"TestCase\" data constructor"
+        (HUnit.TestCase $ HUnit.assertBool "example" True),
+
+    it "is the assumed example for IO() actions"
+        (HUnit.assertBool "example" True),
+
+    it "will show the assertion text if it fails"
+        (HUnit.TestCase $ do
+          innerSpecs <- describe "" [ it "fails" (HUnit.assertBool "trivial" False)]
+          let found = pureHspec innerSpecs !! 2
+          HUnit.assertEqual found " x fails (trivial)" found)
+  ],
+  describe "QuickCheck example" [
+    it "is specified with the \"property\" function"
+        (property $ \ b -> b || True)
+  ],
+  describe "pending example" [
+    it "is specified with the \"pending\" function and an explanation"
+        (pending "message" == Pending "message"),
+
+    it "accepts a message to display in the report"
+        (documentSpec (spec (Pending "t")) == " - example\n     # t")
+  ],
+  describe "hspec" [
+    it "displays each thing being described as a header"
+        (documentGroup [spec Success] !! 1 == "Example"),
+
+    it "displays one row for each requirement"
+        (length (documentGroup testSpecs) == 5),
+
+    it "displays a '-' for successfully implemented requirements"
+        (documentSpec (spec Success) == " - example"),
+
+    it "displays an 'x' for unsuccessfully implmented requirements"
+        (documentSpec (spec $ Fail "whatever") == " x example (whatever)" ),
+
+    it "displays optional details for unsuccessfully implmented requirements"
+        (documentSpec (spec $ Fail "whatever") == " x example (whatever)" ),
+
+    it "displays a '-' for requirements that are pending an example"
+        (documentSpec (spec (Pending "pending")) == " - example\n     # pending" ),
+
+    it "displays a '#' and an additional message for pending examples"
+        (documentSpec (spec (Pending "pending")) == " - example\n     # pending" ),
+
+    it "can output to stdout"
+        (True),
+
+    it "can output to stdout in color"
+        (pending "TODO in the near future, perhaps using System.Console.ANSI?"),
+
+    it "summarizes the time it takes to finish"
+        (any (=="Finished in 0.0000 seconds") (pureHspec testSpecs)),
+
+    it "summarizes the number of examples and failures"
+        (any (=="3 examples, 1 failure") (pureHspec testSpecs))
+  ],
+  describe "quantify (an internal function)" [
+    it "returns an amount and a word given an amount and word"
+        (quantify (1::Int) "thing" == "1 thing"),
+
+    it "returns a singular word given the number 1"
+        (quantify (1::Int) "thing" == "1 thing"),
+
+    it "returns a plural word given a number greater than 1"
+        (quantify (2::Int) "thing" == "2 things"),
+
+    it "returns a plural word given the number 0"
+        (quantify (0::Int) "thing" == "0 things")
+  ]]
diff --git a/hspec.cabal b/hspec.cabal
new file mode 100644
--- /dev/null
+++ b/hspec.cabal
@@ -0,0 +1,48 @@
+name: hspec
+version: 0.2.0
+cabal-version: -any
+build-type: Custom
+license: BSD3
+license-file: LICENSE
+copyright: (c) Trystan Spangler 2011
+maintainer: trystan.s@comcast.net
+build-depends: HUnit >= 1 && <= 2, QuickCheck >= 2.4.0.1 && <= 2.5, base >=4.2 && <=4.3
+stability: experimental
+homepage: https://github.com/trystan/hspec
+package-url:
+bug-reports:
+synopsis: Behavior Driven Development for Haskell
+description: Behavior Driven Development for Haskell
+category: Testing
+author: Trystan Spangler
+tested-with:
+data-files:
+data-dir: ""
+extra-source-files: ./Specs.hs ./src/Test/Hspec/HUnit.hs
+                    ./src/Test/Hspec/Internal.hs ./src/Test/Hspec/QuickCheck.hs
+extra-tmp-files:
+exposed-modules: Test.Hspec Test.Hspec.HUnit Test.Hspec.Internal
+                 Test.Hspec.QuickCheck
+exposed: True
+buildable: True
+build-tools:
+cpp-options:
+cc-options:
+ld-options:
+pkgconfig-depends:
+frameworks:
+c-sources:
+extensions:
+extra-libraries:
+extra-lib-dirs:
+includes:
+install-includes:
+include-dirs:
+hs-source-dirs: . src
+other-modules: Specs
+ghc-prof-options:
+ghc-shared-options:
+ghc-options: -Wall
+hugs-options:
+nhc98-options:
+jhc-options:
diff --git a/src/Test/Hspec.hs b/src/Test/Hspec.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec.hs
@@ -0,0 +1,90 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Test.Hspec
+-- Copyright   :  (c) Trystan Spangler 2011
+-- License     :  modified
+--
+-- Maintainer  : trystan.s@comcast.net
+-- Stability   : experimental
+-- Portability : portable
+--
+-----------------------------------------------------------------------------
+
+
+-- | Hspec is a Behaviour-Driven Development tool for Haskell programmers. BDD is an approach
+-- to software development that combines Test-Driven Development, Domain Driven Design, and
+-- Acceptance Test-Driven Planning. Hspec helps you do the TDD part of that equation, focusing
+-- on the documentation and design aspects of TDD.
+--
+-- Hspec (and the preceding intro) are based on the Ruby library RSpec. Much of what applies to
+-- RSpec also applies to Hspec. Hspec ties together /descriptions/ of behavior and /examples/ of
+-- that behavior. The examples can also be run as tests and the output summarises what needs to
+-- be implemented.
+--
+-- The three functions you'll use the most are 'hspec', 'describe', and 'it'. Here is an
+-- example of functions that format and unformat phone numbers and the specs for them.
+--
+-- > import Test.Hspec
+-- > import Test.Hspec.QuickCheck
+-- > import Test.Hspec.HUnit
+-- > import Test.QuickCheck hiding (property)
+-- > import Test.HUnit
+-- >
+-- > main = hspec mySpecs
+--
+-- Since the specs are often used to tell you what to implement, it's best to start with
+-- undefined functions. Once we have some specs, then you can implement each requirement
+-- one at a time, ensuring that each requirement is met and there is no undocumented behavior.
+--
+-- > unformatPhoneNumber :: String -> String
+-- > unformatPhoneNumber number = undefined
+-- >
+-- > formatPhoneNumber :: String -> String
+-- > formatPhoneNumber number = undefined
+--
+-- The "describe" function takes a list of requirements and examples bound together with the "it" function
+--
+-- > mySpecs = describe "unformatPhoneNumber" [
+--
+-- A boolean expression can act as a requirement's example.
+--
+-- >   it "removes dashes, spaces, and parenthesies"
+-- >       (unformatPhoneNumber "(555) 555-1234" == "5555551234"),
+--
+-- The "pending" function marks a requirement as pending an example. It won't Fail.
+--
+-- >   it "handles non-US phone numbers"
+-- >       (pending "need to look up how other cultures format phone numbers"),
+--
+-- An HUnit "Test" can act as a requirement's example. (must import @Test.Hspec.HUnit@)
+--
+-- >   it "removes the \"ext\" prefix of the extension"
+-- >       (TestCase $ let expected = "5555551234135"
+-- >                       actual   = unformatPhoneNumber "(555) 555-1234 ext 135"
+-- >                   in assertEqual "remove extension" expected actual),
+--
+-- An @IO()@ action is treated like an HUnit "TestCase". (must import @Test.Hspec.HUnit@)
+--
+-- >   it "converts letters to numbers"
+-- >       (do
+-- >         let expected = "6862377"
+-- >         let actual   = unformatPhoneNumber "NUMBERS"
+-- >         assertEqual "letters to numbers" expected actual),
+--
+-- The "property" function allows a QuickCheck property to act as an example. (must import @Test.Hspec.HUnit@)
+--
+-- >   it "can add and add remove formatting without changing the number"
+-- >       (property $ forAll phoneNumber $
+-- >         \ n -> unformatPhoneNumber (formatPhoneNumber n) == n)
+-- >   ]
+-- >
+-- > phoneNumber :: Gen String
+-- > phoneNumber = do
+-- >   nums <- elements [7,10,11,12,13,14,15]
+-- >   vectorOf nums (elements "0123456789")
+--
+module Test.Hspec (
+  Spec(), Result(), describe, it, pending, pureHspec, hHspec, hspec
+) where
+
+import Test.Hspec.Internal
diff --git a/src/Test/Hspec/HUnit.hs b/src/Test/Hspec/HUnit.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec/HUnit.hs
@@ -0,0 +1,44 @@
+{-# OPTIONS -XFlexibleInstances #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Test.Hspec.HUnit
+-- Copyright   :  (c) Trystan Spangler 2011
+-- License     :  modified BSD
+--
+-- Maintainer  : trystan.s@comcast.net
+-- Stability   : experimental
+-- Portability : portable
+--
+-----------------------------------------------------------------------------
+
+
+-- | Importing this module allows you to use an HUnit test case as an example
+-- for a requirement. You can use an explicit TestCase data constructor or
+-- use an IO() action. For an IO() action, any exception means the example
+-- failed; otherwise, it's successfull.
+--
+-- > describe "cutTheDeck" [
+-- >   it "puts the first half of a list after the last half"
+-- >      (TestCase $ assertEqual "cut the deck" [3,4,1,2] (cutTheDeck [1,2,3,4])),
+-- >
+-- >   it "restores an even sized list when cut twice"
+-- >      (assertEqual "cut the deck twice" [3,4,1,2] (cutTheDeck (cutTheDeck [1,2,3,4]))),
+-- >   ]
+-- >
+module Test.Hspec.HUnit (
+) where
+
+import Test.Hspec.Internal
+import qualified Test.HUnit as HU
+
+instance SpecVerifier (IO ()) where
+  it n t = it n (HU.TestCase t)
+
+instance SpecVerifier HU.Test where
+  it n t = do
+    (counts, fails) <- HU.runTestText HU.putTextToShowS t
+    let rows = lines (fails "")
+    if HU.errors counts + HU.failures counts == 0
+      then return (n, Success)
+      else return (n, Fail (rows !! 1))
+
diff --git a/src/Test/Hspec/Internal.hs b/src/Test/Hspec/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec/Internal.hs
@@ -0,0 +1,176 @@
+{-# OPTIONS -XFlexibleInstances #-}
+-----------------------------------------------------------------------------
+--
+-- Module      :  Test.Hspec.Internal
+-- Copyright   :  (c) Trystan Spangler 2011
+-- License     :  modified BSD
+--
+-- Maintainer  : trystan.s@comcast.net
+-- Stability   : experimental
+-- Portability : portable
+--
+-----------------------------------------------------------------------------
+
+
+module Test.Hspec.Internal where
+
+import System.IO
+import Data.List (groupBy)
+import System.CPUTime (getCPUTime)
+import Text.Printf
+import Control.Exception
+
+-- | The result of running an example.
+data Result = Success | Fail String | Pending String
+  deriving Eq
+
+
+-- | Everything needed to specify and show a specific behavior.
+data Spec = Spec {
+                 -- | What is being tested, usually the name of a type.
+                 name::String,
+                 -- | The specific requirement being tested.
+                 requirement::String,
+                 -- | The status of this requirement.
+                 result::Result }
+
+
+-- | Create a set of specifications for a specific type being described.
+-- Once you know what you want specs for, use this.
+--
+-- > describe "abs" [
+-- >   it "returns a positive number given a negative number"
+-- >     (abs (-1) == 1)
+-- >   ]
+--
+describe :: String                -- ^ The name of what is being described, usually a function or type.
+         -> [IO (String, Result)] -- ^ A list of requirements and examples, created by a list of 'it'.
+         -> IO [Spec]
+describe n ss = do
+  ss' <- sequence ss
+  return $ map (\ (req, res) -> Spec n req res) ss'
+
+
+-- | Evaluate a Result. Any exceptions (undefined, etc.) are treated as failures.
+safely :: Result -> IO Result
+safely f = Control.Exception.catch ok failed
+  where ok = f `seq` return f
+        failed e = return $ Fail (show (e :: SomeException))
+
+
+-- | Anything that can be used as an example of a requirement.
+class SpecVerifier a where
+  -- | Create a description and example of a requirement, a list of these
+  -- is used by 'describe'. Once you know what you want to specify, use this.
+  --
+  -- > describe "closeEnough" [
+  -- >   it "is true if two numbers are almost the same"
+  -- >     (1.001 `closeEnough` 1.002),
+  -- >
+  -- >   it "is false if two numbers are not almost the same"
+  -- >     (not $ 1.001 `closeEnough` 1.003)
+  -- >   ]
+  --
+  it :: String           -- ^ A description of this requirement.
+     -> a                -- ^ A example for this requirement.
+     -> IO (String, Result) -- ^ The combined description and result of the example.
+
+
+instance SpecVerifier Bool where
+  it n b = do
+    r <- safely (if b then Success else Fail "")
+    return (n, r)
+
+instance SpecVerifier Result where
+  it n r = return (n, r)
+
+
+-- | Declare an example as not successful or failing but pending some other work.
+-- If you want to track a requirement but don't expect it to succeed or fail yet, use this.
+--
+-- > describe "fancyFormatter" [
+-- >   it "can format text in a way that everyone likes"
+-- >     (pending "waiting for clarification from the designers")
+-- >   ]
+--
+pending :: String  -- ^ An explanation for why this requirement is pending.
+        -> Result
+pending = Pending
+
+
+-- | Create a document of the given specs.
+documentSpecs :: [Spec] -> [String]
+documentSpecs = concatMap documentGroup . groupBy (\ a b -> name a == name b)
+
+
+-- | Create a document of the given group of specs.
+documentGroup :: [Spec] -> [String]
+documentGroup specGroup = "" : name (head specGroup) : map documentSpec specGroup
+
+
+-- | Create a document of the given spec.
+documentSpec :: Spec -> String
+documentSpec spec  = case result spec of
+                Success    -> " - " ++ requirement spec
+                Fail ""    -> " x " ++ requirement spec
+                Fail s     -> " x " ++ requirement spec ++ " (" ++ s ++ ")"
+                Pending s  -> " - " ++ requirement spec ++ "\n     # " ++ s
+
+
+-- | Create a summary of how long it took to run the examples.
+timingSummary :: Double -> String
+timingSummary t = printf "Finished in %1.4f seconds" (t / (10.0^(12::Integer)) :: Double)
+
+
+-- | Create a summary of how many specs exist and how many examples failed.
+successSummary :: [Spec] -> String
+successSummary ss = quantify (length ss) "example" ++ ", " ++ quantify failed "failure"
+    where failed = length $ filter (isFailure.result) ss
+          isFailure (Fail _) = True
+          isFailure _        = False
+
+
+-- | Create a document of the given specs.
+-- This does not track how much time it took to check the examples. If you want
+-- a description of each spec and don't need to know how long it tacks to check,
+-- use this.
+pureHspec :: [Spec]   -- ^ The specs you are interested in.
+          -> [String] -- ^ A human-readable summary of the specs and which are unsuccessfully implemented.
+pureHspec ss = documentSpecs ss ++ [ "", timingSummary 0, "", successSummary ss]
+
+
+-- | Create a document of the given specs and write it to stdout.
+-- This does track how much time it took to check the examples. Use this if
+-- you want a description of each spec and do need to know how long it tacks
+-- to check the examples or want to write to stdout.
+hspec :: IO [Spec] -> IO ()
+hspec = hHspec stdout
+
+
+-- | Create a document of the given specs and write it to the given handle.
+-- This does track how much time it took to check the examples. Use this if
+-- you want a description of each spec and do need to know how long it tacks
+-- to check the examples or want to write to a file or other handle.
+--
+-- > writeReport filename specs = withFile filename WriteMode (\ h -> hHspec h specs)
+--
+hHspec :: Handle     -- ^ A handle for the stream you want to write to.
+       -> IO [Spec]  -- ^ The specs you are interested in.
+       -> IO ()
+hHspec h ss = do
+  t0 <- getCPUTime
+  ss' <- ss
+  mapM_ (hPutStrLn h) $ documentSpecs ss'
+  t1 <- getCPUTime
+  mapM_ (hPutStrLn h) [ "", timingSummary (fromIntegral $ t1 - t0), "", successSummary ss']
+
+
+
+-- | Create a more readable display of a quantity of something.
+quantify :: Num a => a -> String -> String
+quantify 1 s = "1 " ++ s
+quantify n s = show n ++ " " ++ s ++ "s"
+
+
+
+
diff --git a/src/Test/Hspec/QuickCheck.hs b/src/Test/Hspec/QuickCheck.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec/QuickCheck.hs
@@ -0,0 +1,46 @@
+-----------------------------------------------------------------------------
+--
+-- Module      :  Test.Hspec.QuickCheck
+-- Copyright   :  (c) Trystan Spangler 2011
+-- License     :  modified BSD
+--
+-- Maintainer  : trystan.s@comcast.net
+-- Stability   : experimental
+-- Portability : portable
+--
+-----------------------------------------------------------------------------
+
+
+-- | Importing this module allows you to use a QuickCheck property as an example
+-- for a requirement. Use the 'property' function to indicate a QuickCkeck property.
+--
+-- > describe "cutTheDeck" [
+-- >   it "puts the first half of a list after the last half"
+-- >      (property $ \ xs -> let top = take (length xs `div` 2) xs
+-- >                              bot = drop (length xs `div` 2) xs
+-- >                          in cutTheDeck xs == bot ++ top),
+-- >
+-- >   it "restores an even sized list when cut twice"
+-- >      (property $ \ xs -> even (length xs) ==> cutTheDeck (cutTheDeck xs) == xs)
+-- >   ]
+--
+module Test.Hspec.QuickCheck (
+  property
+) where
+
+import Test.Hspec.Internal
+import qualified Test.QuickCheck as QC
+
+data QuickCheckProperty a = QuickCheckProperty a
+
+property :: QC.Testable a => a -> QuickCheckProperty a
+property = QuickCheckProperty
+
+instance QC.Testable t => SpecVerifier (QuickCheckProperty t) where
+  it n (QuickCheckProperty p) = do
+    r <- QC.quickCheckResult p
+    case r of
+      QC.Success {}           -> return (n, Success)
+      f@(QC.Failure {})       -> return (n, Fail (QC.reason f))
+      g@(QC.GaveUp {})        -> return (n, Fail ("Gave up after " ++ quantify (QC.numTests g) "test" ))
+      QC.NoExpectedFailure {} -> return (n, Fail ("No expected failure"))
