diff --git a/.ghci b/.ghci
new file mode 100644
--- /dev/null
+++ b/.ghci
@@ -0,0 +1,1 @@
+:set -isrc-lib:src-test:dist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,18 +1,28 @@
-# **ToolShed**.
+# **ToolShed**
 
-This is **ToolShed**, a library of unconnected utilities.
+[![Hackage](https://img.shields.io/hackage/v/toolshed.svg)](https://hackage.haskell.org/package/toolshed) [![Build Status](https://travis-ci.org/functionalley/ToolShed.svg?branch=master)](https://travis-ci.org/functionalley/ToolShed)
 
+This is "**ToolShed**", a library of unconnected utilities.
+
 ## Installation
 
 It can be built and installed using [Cabal](https://www.haskell.org/cabal/users-guide/installing-packages.html).
 
 ## License
 
-For information on copying and distributing this package, see the file **LICENSE** in this directory.
+For information on copying and distributing this package, see the file "**LICENSE**" in this directory.
 
 ## Bug-reporting
 
-Bug-reports should be emailed to <toolshed *at* functionalley *dot* eu>.
+Bug-reports should be emailed to <toolshed@functionalley.eu>.
+
+## Testing
+
+The test-suite can be run using:
+
+    cabal configure --enable-tests;
+    cabal build;
+    cabal test --show-details=always;
 
 ## Author
 
diff --git a/changelog.markdown b/changelog.markdown
--- a/changelog.markdown
+++ b/changelog.markdown
@@ -1,91 +1,131 @@
-# 2010-11-18 Dr. Alistair Ward <toolshed at functionalley dot eu>
+# 2010-11-18 Dr. Alistair Ward <toolshed@functionalley.eu>
 
 ## 0.9.0.0
-	* First version of the package.
+* First version of the package.
+
 ## 0.10.0.0
-	* Created **src/ToolShed/** sub-directory & then modified module-names accordingly.
-	* Removed the module **Pair**, & relocated its only function to the sole caller in the package **Bridge**.
-	* Added a makefile.
-	* Qualified identifiers used in error-messages.
+* Created sub-directory "**src/ToolShed/**" & then modified module-names accordingly.
+* Removed the module "**Pair**", & relocated its only function to the sole caller in the package "**Bridge**".
+* Added a makefile.
+* Qualified identifiers used in error-messages.
+
 ## 0.10.0.1
-	* Tested with ghc-7.0.1, & conditionally replaced use of the package **parallel** with **deepseq**, in the module **TimePure**.
+* Tested with **ghc-7.0.1**, & conditionally replaced use of the package "**parallel**" with "**deepseq**", in the module "**TimePure**".
+
 ## 0.10.1.0
-	* Added `ToolShed.Arithmetic.nCr`, **ToolShed.Options** & **ToolShed.Package**.
+* Added `ToolShed.Arithmetic.nCr`, **ToolShed.Options** & **ToolShed.Package**.
+
 ## 0.10.2.0
-	* Renamed package from **ToolShed** to **toolshed**, for compatibility with Debian's *.deb*-format.
+* Renamed package "**ToolShed**" to "**toolshed**", for compatibility with Debian's *.deb*-format.
+
 ## 0.11.0.0
-	* Added manually controlled **llvm** flag to the *.cabal*-file.
-	* Removed the module **ToolShed.Package**, for which **Distribution.Package.PackageIdentifier** is a suitable alternative.
-	* Added **NOINLINE** pragma to each function in module **Unsafe**.
-	* Relocated `mean` & `nCr` from **ToolShed.Arithmetic**, to the package **factory**.
-	* Added function `ListPlus.groupComparing`.
-	* Changed identifier for type-parameters, to better reflect its role.
-	* Relocated the remaining rather pointless functions from the module **ToolShed.Arithmetic** & deleted it.
-	* Added module **ToolShed.Defaultable**, & derived class `ToolShed.Options.Options` from it.
+* Added manually controlled flag "**llvm**" to the *.cabal*-file.
+* Removed the module "**ToolShed.Package**", for which "**Distribution.Package.PackageIdentifier**" is a suitable alternative.
+* Added pragma "**NOINLINE**" to each function in module "**Unsafe**".
+* Relocated `mean` & `nCr` from **ToolShed.Arithmetic**, to the package "**factory**".
+* Added function `ListPlus.groupComparing`.
+* Changed identifier for type-parameters, to better reflect its role.
+* Relocated the remaining rather pointless functions from the module "**ToolShed.Arithmetic**" & deleted it.
+* Added module "**ToolShed.Defaultable**", & derived class `ToolShed.Options.Options` from it.
+
 ## 0.11.1.0
-	* Added functions `merge` & `mergeBy` to module **ToolShed.ListPlus** & exported a new type-synonym `ToolShed.ListPlus.ChunkLength`.
-	* Uploaded to [Hackage](http://hackage.haskell.org/packages/hackage.html).
+* Added functions `merge` & `mergeBy` to module "**ToolShed.ListPlus**" & exported a new type-synonym `ToolShed.ListPlus.ChunkLength`.
+* Uploaded to [Hackage](http://hackage.haskell.org/package/toolshed).
+
 ## 0.12.0.0
-	* Added modules **ToolShed.TimeAction** to measure the CPU-seconds required for an IO-action, & **Pair**.
+* Added modules "**ToolShed.TimeAction**" to measure the CPU-seconds required for an IO-action, & "**Pair**".
+
 ## 0.12.0.1
-	* Removed unnecessary type-context `Ord` from `ToolShed.ListPus.mergeBy` & reimplemented `ToolShed.ListPus.merge` in terms of `ToolShed.ListPus.mergeBy`.
-	* Added `ToolShed.ListPlus.runLengthEncode` & `ToolShed.ListPlus.runLengthDecode`.
+* Removed unnecessary type-context `Ord` from `ToolShed.ListPus.mergeBy` & reimplemented `ToolShed.ListPus.merge` in terms of `ToolShed.ListPus.mergeBy`.
+* Added `ToolShed.ListPlus.runLengthEncode` & `ToolShed.ListPlus.runLengthDecode`.
+
 ## 0.13.0.0
-	* Removed module **ToolShed.Unsafe**.
-	* Renamed:
-		**ToolShed.ListPlus** to **ToolShed.Data.List**
-		**ToolShed.Pair** to **ToolShed.Data.Pair**
-		**ToolShed.TimeAction** to **ToolShed.System.TimeAction**
-		**ToolShed.TimePure** to **ToolShed.System.TimePure**
-	* Migrated **ToolShed.Data.List.RunLengthCode** & associated functions, into a new module **ToolShed.Data.List.Runlength**.
-	* Migrated **ToolShed.Data.List.Splits** & associated functions, into a new module **ToolShed.Data.List.Splits**.
-	* Replaced function `ToolShed.Data.List.groupComparing` with the more useful `ToolShed.Data.List.equalityBy`, which can be used with either `Data.List.groupBy` or `Data.List.nubBy`.
-	* Added instances of `ToolShed.SelfValidate.SelfValidator` for `Data.Maybe.Maybe` `(,)`, `Data.Set.Set`, `Data.Map.Map` & `Data.Array.IArray.Array`.
-	* Added instance of `ToolShed.Defaultable.Defaultable` for `(,)`.
-	* Added functions `ToolShed.Data.List.showListWith`, `ToolShed.Data.List.permutations`, `ToolShed.Data.List.gatherBy`, `ToolShed.Data.List.findConvergenceBy`, `ToolShed.Data.List.findConvergence`, `ToolShed.Data.List.gather`.
-	* Added modules **ToolShed.System.File** & **ToolShed.System.Random**.
-	* Added method `ToolShed.SelfValidate.getErrors`, & supporting functions `ToolShed.SelfValidate.getFirstErrors` & `ToolShed.SelfValidate.extractErrors`.
-	* Create module **ToolShed.Arbitrary.* **.
-	* Added **Main**, **ToolShed.Test.QuickChecks** & **ToolShed.Test.Data.List** to facilitate testing.
-	* Removed `ToolShed.Data.Pair.both`.
-	` Replaced `System` with `System.Environment` & `System.Exit`.
-	* Removed dependency on **haskell98**.
+* Removed module "**ToolShed.Unsafe**".
+* Renamed:
+	+ **ToolShed.ListPlus** to **ToolShed.Data.List**
+	+ **ToolShed.Pair** to **ToolShed.Data.Pair**
+	+ **ToolShed.TimeAction** to **ToolShed.System.TimeAction**
+	+ **ToolShed.TimePure** to **ToolShed.System.TimePure**
+* Migrated **ToolShed.Data.List.RunLengthCode** & associated functions, into a new module "**ToolShed.Data.List.Runlength**".
+* Migrated **ToolShed.Data.List.Splits** & associated functions, into a new module "**ToolShed.Data.List.Splits**".
+* Replaced function `ToolShed.Data.List.groupComparing` with the more useful `ToolShed.Data.List.equalityBy`, which can be used with either `Data.List.groupBy` or `Data.List.nubBy`.
+* Added instances of `ToolShed.SelfValidate.SelfValidator` for `Data.Maybe.Maybe` `(,)`, `Data.Set.Set`, `Data.Map.Map` & `Data.Array.IArray.Array`.
+* Added instance of `ToolShed.Defaultable.Defaultable` for `(,)`.
+* Added functions
+	+ `ToolShed.Data.List.showListWith`,
+	+ `ToolShed.Data.List.permutations`,
+	+ `ToolShed.Data.List.gatherBy`,src-lib/ToolShed/Test/ReversibleIO.hs
+	+ `ToolShed.Data.List.findConvergenceBy`,
+	+ `ToolShed.Data.List.findConvergence`,
+	+ `ToolShed.Data.List.gather`.
+* Added modules "**ToolShed.System.File**" & "**ToolShed.System.Random**".
+* Added method `ToolShed.SelfValidate.getErrors`, & supporting functions `ToolShed.SelfValidate.getFirstErrors` & `ToolShed.SelfValidate.extractErrors`.
+* Create module "**ToolShed.Arbitrary.\* **".
+* Added **Main**, **ToolShed.Test.QuickChecks** & **ToolShed.Test.Data.List** to facilitate testing.
+* Removed `ToolShed.Data.Pair.both`.
+` Replaced `System` with `System.Environment` & `System.Exit`.
+* Removed dependency on **haskell98**.
+
 ## 0.14.0.0
-	* Defined package's name using program's name, in **Main.hs**.
-	* Checked package **Base** exports `Data.Tuple.swap`, in **ToolShed.Arbitrary.Array**.
-	* Relocated **ToolShed.Arbitrary** to **ToolShed.Test.QuickCheck.Arbitrary**.
-	* Added **ToolShed.Test.ReversibleBoundedEnum**, **ToolShed.Test.ReversibleEnum**, **ToolShed.Test.ReversibleIO**, & **ToolShed.Test.SelfValidate**.
-	* Amended `ToolShed.System.File.locate` to deal with absolute file-paths.
-	* Replaced legacy calls to `Data.Map.fold` & `Data.Set.fold`, with more expicit calls to `Data.Map.foldr` & `Data.Set.foldr` from a more recent version of the **containers** package.
-	* Added instance of `ToolShed.SelfValidate.SelfValidator` for `(,,)`.
-	* Trapped null list in `ToolShed.System.Random.select`.
-	* Added functions `ToolShed.Data.List.nub'` & 'ToolShed.Data.List.hasDuplicates'.
-	* Migrated functions `gather`, `gatherBy`, `hasDuplicates` which merely operate on `Data.Foldable.Foldable` types from module **ToolShed.Data.List**, into new module **ToolShed.Data.Foldable**.
+* Defined package's name using program's name, in **Main.hs**.
+* Checked package "**Base**" exports `Data.Tuple.swap`, in **ToolShed.Arbitrary.Array**.
+* Relocated **ToolShed.Arbitrary** to **ToolShed.Test.QuickCheck.Arbitrary**.
+* Added **ToolShed.Test.ReversibleBoundedEnum**, **ToolShed.Test.ReversibleEnum**, **ToolShed.Test.ReversibleIO**, & **ToolShed.Test.SelfValidate**.
+* Amended `ToolShed.System.File.locate` to deal with absolute file-paths.
+* Replaced legacy calls to `Data.Map.fold` & `Data.Set.fold`, with more expicit calls to `Data.Map.foldr` & `Data.Set.foldr` from a more recent version of the **containers** package.
+* Added instance of `ToolShed.SelfValidate.SelfValidator` for `(,,)`.
+* Trapped null list in `ToolShed.System.Random.select`.
+* Added functions `ToolShed.Data.List.nub'` & 'ToolShed.Data.List.hasDuplicates'.
+* Migrated functions `gather`, `gatherBy`, `hasDuplicates` which merely operate on `Data.Foldable.Foldable` types from module "**ToolShed.Data.List**", into new module "**ToolShed.Data.Foldable**".
+
 ## 0.15.0.0
-	* Refactored **ToolShed.Test.QuickChecks**.
-	* Added type `ToolShed.Data.List.Matches` & function `ToolShed.Data.List.permutationsBy`.
-	* Trapped the case of a null list supplied to `ToolShed.Data.List.permutationsBy`.
-	* Re-implemented `ToolShed.System.Random.shuffle`, using the Fisher-Yates algorithm; which also improved the efficiency.
-	* Trapped special cases in `ToolShed.System.Random.generateSelection`.
-	* Added modules **ToolShed.Test.System.Random**, **ToolShed.Data.Triple**, **ToolShed.Data.Quadruple**, **ToolShed.Test.Data.Triple**, & **ToolShed.Test.Data.Quadruple**.
-	* Explicitly closed standard-input in the executable.
-	* Replaced calls to `error` from inside the IO-monad, with `Control.Monad.fail`.
-	* Added an instance for `(,,)`, to **ToolShed.Defaultable.Defaultable**.
-	* Corrected version-string in **Main** used in **--version** option.
-	* Corrected the output of `Main.main.optDescrList.printVersion`.
+* Refactored **ToolShed.Test.QuickChecks**.
+* Added type `ToolShed.Data.List.Matches` & function `ToolShed.src-lib/ToolShed/Test/ReversibleIO.hsData.List.permutationsBy`.
+* Trapped the case of a null list supplied to `ToolShed.Data.List.permutationsBy`.
+* Re-implemented `ToolShed.System.Random.shuffle`, using the Fisher-Yates algorithm; which also improved the efficiency.
+* Trapped special cases in `ToolShed.System.Random.generateSelection`.
+* Added modules **ToolShed.Test.System.Random**, **ToolShed.Data.Triple**, **ToolShed.Data.Quadruple**, **ToolShed.Test.Data.Triple**, & **ToolShed.Test.Data.Quadruple**.
+* Explicitly closed standard-input in the executable.
+* Replaced calls to `error` from inside the IO-monad, with `Control.Monad.fail`.
+* Added an instance for `(,,)`, to **ToolShed.Defaultable.Defaultable**.
+* Corrected version-string in **Main** used in option "**--version**".
+* Corrected the output of `Main.main.optDescrList.printVersion`.
+
 ## 0.15.0.1
-	* Tested with **haskell-platform-2013.2.0.0**.
-	* Replaced preprocessor-directives with **build-depends** constraints in the *.cabal*-file.
-	* In module **ToolShed.System.File**, replaced `Control.Exception.throw` with `Control.Exception.throwIO`.
-	* Replaced all instances of `(<$>)` with `fmap` to avoid ambiguity between **Control.Applicative** & **Prelude** which (from **base-4.8**) also exports this symbol.
+* Tested with **haskell-platform-2013.2.0.0**.
+* Replaced preprocessor-directives with **build-depends** constraints in the *.cabal*-file.
+* In module "**ToolShed.System.File**", replaced `Control.Exception.throw` with `Control.Exception.throwIO`.
+* Replaced all instances of `(<$>)` with `fmap` to avoid ambigusrc-lib/ToolShed/Test/ReversibleIO.hsity between modules "**Control.Applicative**" & "**Prelude**" which (from package "**base-4.8**") also exports this symbol.
+
 ## 0.16.0.0
-	* Corrected the copyright dates in **Main**.
-	* Renamed module **ToolShed.Test.QuickCheck.Arbitrary.ArrayElem** to **ToolShed.Test.QuickCheck.Arbitrary.Array**, overwriting the module originally of that name which pointlessly defined an instance of `Test.QuickCheck.Arbitrary` for an array with an unbounded index.
-	* Added **Default-language**-specification to the *.cabal*-file.
-	* Added file **README.markdown**.
-	* Converted this file to markdown-format.
-	* Replaced `System.Exit.exitWith System.Exit.ExitSuccess` with `System.Exit.exitSuccess`.
-	* Added module **Test.QuickCheck.Result**.
-	* Moved the entry-point to the test-suite from **Main.hs** to **Test.hs** to integrate with **cabal**.
-	* Partitioned the source-files into **src-lib** & **src-test** directories, & referenced them individually from the *.cabal*-file to avoid repeated compilation.
+* Corrected the copyright dates in **Main**.
+* Renamed module "**ToolShed.Test.QuickCheck.Arbitrary.ArrayElem**" to "**ToolShed.Test.QuickCheck.Arbitrary.Array**", overwriting the module originally of that name which pointlessly defined an instance of `Test.QuickCheck.Arbitrary` for an array with an unbounded index.
+* Added **Default-language**-specification to the *.cabal*-file.
+* Added file "**README.markdown**".
+* Converted this file to markdown-format.
+* Replaced `System.Exit.exitWith System.Exit.ExitSuccess` with `System.Exit.exitSuccess`.
+* Added module "**Test.QuickCheck.Result**".
+* Moved the entry-point to the test-suite from module "**Main.hs**" to "**Test.hs**" to integrate with **cabal**.
+* Partitioned the source-files into directories "**src-lib**" & "**src-test**", & referenced them individually from the *.cabal*-file to avoid repeated compilation.
 
+## 0.17.0.0
+* Corrected the markdown-syntax in this file.
+* Reverted to calling "**error**" rather than "**Control.Monad.fail**", since the **String**-argument for the latter is discarded in **Monad**-implementations other than **IO**.
+* Uploaded to [GitHub](https://github.com/functionalley/ToolShed.git).
+* Simplified file **src-test/Main.hs**.
+* Relaxed test **prop_shuffleDistribution** in module **ToolShed.Test.System.Random**.
+* Added file **.travis.yml** to control testing by <https://docs.travis-ci.com>.
+* Added file **.ghci**.
+* Removed module **ToolShed.Defaultable**, since **Data.Default** is a drop-in replacement.
+* Added functions **ToolShed.Test.ReversibleIO.readTrailingGarbage** & **ToolShed.Test.ReversibleIO.readPrependedWhiteSpace**.
+* Added function **ToolShed.Data.List.interleave** with corresponding quickcheck-tests.
+* Added module **ToolShed.Test.Ix** to facilitate testing instances of class **Data.Array.IArray.Ix**.
+* Added module **ToolShed.Data.Array.IArray**.
+* Added function **ToolShed.Data.String.deTab**.
+* Generalised function **ToolShed.System.Random.select** to accept any **Data.Foldable.Foldable** rather than merely a list, & to return **Maybe** rather than an error on receipt of null.
+* Added fuzzy matching function **ToolShed.Data.List.measureJaroDistance** & associated **HUnit** & **Quickcheck** tests.
+* Tested with **ghc-8.0.1**.
+## 0.17.0.1
+* Modified Travis-CI configuration.
+## 0.17.0.2
+* Removed **-prof** from profiling-flags in Cabal-configuration.
diff --git a/copyright b/copyright
--- a/copyright
+++ b/copyright
@@ -1,5 +1,5 @@
 Author:
-	Dr. Alistair Ward <toolshed at functionalley dot eu>.
+	Dr. Alistair Ward <toolshed@functionalley.eu>.
 
 Copyright:
 	Copyright (C) 2010-2013 Dr. Alistair Ward. All Rights Reserved.
diff --git a/src-lib/ToolShed/Data/Array/IArray.hs b/src-lib/ToolShed/Data/Array/IArray.hs
new file mode 100644
--- /dev/null
+++ b/src-lib/ToolShed/Data/Array/IArray.hs
@@ -0,0 +1,47 @@
+{-
+	Copyright (C) 2013 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]
+
+	* Additions to module "Data.Array.IArray".
+-}
+
+module ToolShed.Data.Array.IArray(
+-- * Functions
+	adjust
+) where
+
+import qualified	Data.Array.IArray
+import			Data.Array.IArray((!), (//))
+
+-- | Update a single element of the specified array.
+adjust :: (
+	Data.Array.IArray.Ix		i,
+	Data.Array.IArray.IArray	a e
+ )
+	=> (e -> e)	-- ^ Mutator.
+	-> i		-- ^ Index.
+	-> a i e
+	-> a i e
+adjust mutator i array	= array // [
+	(
+		i,
+		mutator $ array ! i
+	) -- Pair.
+ ]
diff --git a/src-lib/ToolShed/Data/Foldable.hs b/src-lib/ToolShed/Data/Foldable.hs
--- a/src-lib/ToolShed/Data/Foldable.hs
+++ b/src-lib/ToolShed/Data/Foldable.hs
@@ -37,14 +37,18 @@
 
 	* The groups are returned in ascending order, whilst their elements remain in their original order.
 -}
-gatherBy :: (Data.Foldable.Foldable f, Ord b) => (a -> b) -> f a -> [[a]]
+gatherBy
+	:: (Data.Foldable.Foldable foldable, Ord b)
+	=> (a -> b)	-- ^ Function to apply before testing for equality.
+	-> foldable a	-- ^ The input data.
+	-> [[a]]
 gatherBy f	= Data.Map.elems . Data.Foldable.foldr (uncurry (Data.Map.insertWith (++)) . (f &&& return {-to List-monad-})) Data.Map.empty
 
 -- | A specific instance of 'gatherBy'.
-gather :: (Data.Foldable.Foldable f, Ord a) => f a -> [[a]]
+gather :: (Data.Foldable.Foldable foldable, Ord a) => foldable a -> [[a]]
 gather	= gatherBy id
 
 -- | Whether the specified collection contains any equal items.
-hasDuplicates :: (Data.Foldable.Foldable f, Ord a) => f a -> Bool
+hasDuplicates :: (Data.Foldable.Foldable foldable, Ord a) => foldable a -> Bool
 hasDuplicates	= any ((> 1) . length) . gather
 
diff --git a/src-lib/ToolShed/Data/List.hs b/src-lib/ToolShed/Data/List.hs
--- a/src-lib/ToolShed/Data/List.hs
+++ b/src-lib/ToolShed/Data/List.hs
@@ -1,5 +1,5 @@
 {-
-	Copyright (C) 2010 Dr. Alistair Ward
+	Copyright (C) 2010-2015 Dr. Alistair Ward
 
 	This program is free software: you can redistribute it and/or modify
 	it under the terms of the GNU General Public License as published by
@@ -31,7 +31,9 @@
 	equalityBy,
 	findConvergence,
 	findConvergenceBy,
+	interleave,
 	linearise,
+	measureJaroDistance,
 	merge,
 	mergeBy,
 	nub',
@@ -45,10 +47,11 @@
 ) where
 
 import qualified	Control.Arrow
-import			Control.Arrow((&&&))
+import			Control.Arrow((&&&),(***))
 import qualified	Data.IntSet
 import qualified	Data.List
 import qualified	Data.Set
+import qualified	Data.Tuple
 
 -- | The length of the chunks into which a list is split.
 type ChunkLength	= Int
@@ -123,7 +126,7 @@
 
 	* A specific instance of 'permutationsBy', in which no filtering of subsequent lists is performed after each item is selected.
 
-	* NB: differs from 'Data.List.permutations', which selects items from a single input list.
+	* N.B.: differs from 'Data.List.permutations', which selects items from a single input list.
 -}
 permutations :: [[a]] -> [[a]]
 permutations	= permutationsBy (\_ _ -> True)
@@ -150,6 +153,11 @@
 linearise []			= []
 linearise ((l, r) : remainder)	= l : r : linearise remainder	-- Recurse.
 
+-- | Interleaves the specified lists, taking the first item from the first list.
+interleave :: [a] -> [a] -> [a]
+interleave (x : xs) ys	= x : interleave ys xs
+interleave _ ys		= ys
+
 {- |
 	* Merge two sorted lists, according to the specified order, to product a single sorted list.
 
@@ -172,7 +180,7 @@
 {- |
 	* Take until the specified predicate is satisfied; /including/ the item which satisfied it.
 
-	* NB: @takeWhile (not . test)@ would return one fewer item.
+	* N.B.: @takeWhile (not . test)@ would return one fewer item.
 -}
 takeUntil
 	:: (a -> Bool)	-- ^ Predicate, used to determine the last item taken.
@@ -200,4 +208,49 @@
 -- | A specialisation of 'showListWith'.
 showListWithString :: Show element => (String, String, String) -> [element] -> ShowS
 showListWithString (startDelimiter, separator, endDelimiter)	= foldr (.) (showString endDelimiter) . (showString startDelimiter :) . Data.List.intersperse (showString separator) . map shows
+
+{- |
+	* Measures the /distance/ between two lists (typically Strings).
+
+	* The operation is /commutative/; it doesn't matter about the order of the arguments.
+
+	* The result ranges from /0/ when they're completely dissimilar, to /1/ when identical.
+
+	* <https://lingpipe-blog.com/2006/12/13/code-spelunking-jaro-winkler-string-comparison>.
+-}
+measureJaroDistance :: (Eq a, Fractional distance) => ([a], [a]) -> distance
+measureJaroDistance pair
+	| uncurry (==) pair	= 1
+	| nMatches == 0		= 0	-- Guard against divide-by-zero.
+	| otherwise		= sum [
+		fMatches / fromIntegral l,
+		fMatches / fromIntegral l',
+		1 - fromIntegral (
+			foldr (
+				\cc	-> if uncurry (==) cc then id else succ
+			) (0 :: Int) $ uncurry zip matchesPair	-- Count transpositions; matches which occur in a different order.
+		) / (
+			2 {-compensate for double counting-} * fMatches
+		)
+	] / 3 {-normalise: each component of the above sum is in the closed unit interval-}
+	where
+		l, l'	:: Int
+		(l, l')	= length *** length $ pair
+
+		findMatches :: Eq a => ([a], [a]) -> [a]
+		findMatches	= uncurry slave . (zip [0 ..] *** zip [0 ..])	where
+			slave :: Eq a => [(Int, a)] -> [(Int, a)] -> [a]
+			slave [] _		= []	-- There's nothing to match.
+			slave _ []		= []	-- Ignore any remaining 'xs', since there's nothing against which to match.
+			slave ((i, x) : xs) ys	= case span (
+				uncurry (||) . (
+					(> pred (max l l' `div` 2)) . abs . (i -) *** (x /=)
+				) -- Reject either mismatches, or matches which occur outside a maximum separation.
+			 ) ys of
+				(matchFailures, _ : untested)	-> x : slave xs (matchFailures ++ untested)	-- Remove the matched datum, so that it can't be matched against again.
+				_				-> slave xs ys					-- Failed to match 'x' in 'ys'.
+
+		matchesPair@(matches, _)	= findMatches &&& findMatches . Data.Tuple.swap $ pair
+		nMatches			= length matches
+		fMatches			= fromIntegral nMatches	-- Translate to the return-type.
 
diff --git a/src-lib/ToolShed/Data/String.hs b/src-lib/ToolShed/Data/String.hs
new file mode 100644
--- /dev/null
+++ b/src-lib/ToolShed/Data/String.hs
@@ -0,0 +1,45 @@
+{-
+	Copyright (C) 2016 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Miscellaneous String-orientated functions.
+-}
+
+module ToolShed.Data.String(
+-- * Functions
+	deTab
+) where
+
+-- | Replaces any embedded tab-characters with the appropriate number of spaces.
+deTab
+	:: Int	-- ^ Tab-length.
+	-> String
+	-> String
+deTab tabLength
+	| tabLength < 0		= error . showString "ToolShed.Data.String.deTab:\ttab-length=" $ shows tabLength " must be negative."
+	| tabLength == 0	= filter (/= '\t')
+	| otherwise		= slave 0
+	where
+		slave :: Int -> String -> String
+		slave _ []	= []	-- Terminate.
+		slave i (c : s)	= case c of
+			'\t'	-> replicate (tabLength - mod i tabLength) ' ' ++ slave 0 s
+			'\r'	-> c : slave 0 s
+			'\n'	-> c : slave 0 s
+			_	-> c : slave (succ i) s
+
diff --git a/src-lib/ToolShed/Defaultable.hs b/src-lib/ToolShed/Defaultable.hs
deleted file mode 100644
--- a/src-lib/ToolShed/Defaultable.hs
+++ /dev/null
@@ -1,36 +0,0 @@
-{-
-	Copyright (C) 2011 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	A simple interface which data-types with a default-value can implement.
--}
-
-module ToolShed.Defaultable(
--- * Type-classes
-	Defaultable(..)
-) where
-
--- | An interface to which data which have a default-value can adhere.
-class Defaultable a	where
-	defaultValue	:: a	-- ^ The default value of the data-type.
-
-instance (Defaultable a, Defaultable b) => Defaultable (a, b)	where
-	defaultValue	= (defaultValue, defaultValue)
-
-instance (Defaultable a, Defaultable b, Defaultable c) => Defaultable (a, b, c)	where
-	defaultValue	= (defaultValue, defaultValue, defaultValue)
diff --git a/src-lib/ToolShed/Options.hs b/src-lib/ToolShed/Options.hs
--- a/src-lib/ToolShed/Options.hs
+++ b/src-lib/ToolShed/Options.hs
@@ -1,5 +1,5 @@
 {-
-	Copyright (C) 2011 Dr. Alistair Ward
+	Copyright (C) 2011-2015 Dr. Alistair Ward
 
 	This program is free software: you can redistribute it and/or modify
 	it under the terms of the GNU General Public License as published by
@@ -25,8 +25,8 @@
 	Options(..)
 ) where
 
-import qualified	ToolShed.Defaultable
+import qualified	Data.Default
 
--- | Similar to the class 'Text.Regex.Base.RegexLike.RegexOptions'.
-class ToolShed.Defaultable.Defaultable a => Options a	where
+-- | The required interface.
+class Data.Default.Default a => Options a	where
 	blankValue	:: a	-- ^ The /undefined/ state of the data-type, which may be literal, but could alternatively be a logical starting value.
diff --git a/src-lib/ToolShed/SelfValidate.hs b/src-lib/ToolShed/SelfValidate.hs
--- a/src-lib/ToolShed/SelfValidate.hs
+++ b/src-lib/ToolShed/SelfValidate.hs
@@ -23,7 +23,7 @@
 module ToolShed.SelfValidate(
 -- * Type-classes
 	SelfValidator(..),
--- ** Functions
+-- * Functions
 	getFirstError,
 	extractErrors
 ) where
diff --git a/src-lib/ToolShed/System/File.hs b/src-lib/ToolShed/System/File.hs
--- a/src-lib/ToolShed/System/File.hs
+++ b/src-lib/ToolShed/System/File.hs
@@ -102,5 +102,5 @@
 
 	case reads fileContents of
 		[(x, _)]	-> return {-to IO-monad-} (filePath, x)	-- CAVEAT: discards any unconsumed text.
-		_		-> fail $ "ToolShed.System.File.fromFile:\tfailed to parse file=" ++ show filePath
+		_		-> error . showString "ToolShed.System.File.fromFile:\tfailed to parse file=" $ shows filePath "."
 
diff --git a/src-lib/ToolShed/System/Random.hs b/src-lib/ToolShed/System/Random.hs
--- a/src-lib/ToolShed/System/Random.hs
+++ b/src-lib/ToolShed/System/Random.hs
@@ -31,6 +31,7 @@
 ) where
 
 import qualified	Control.Arrow
+import qualified	Data.Foldable
 import qualified	Data.Sequence
 import			Data.Sequence((><), ViewL((:<)))
 import qualified	System.Random
@@ -40,7 +41,7 @@
 randomGens	= uncurry (:) . Control.Arrow.second randomGens {-recurse-} . System.Random.split
 
 {- |
-	* Shuffles the specified finite list, using the /Fisher-Yates/ algorithm; <http://en.wikipedia.org/wiki/Fisher-Yates_shuffle>.
+	* Shuffles the specified finite list, using the /Fisher-Yates/ algorithm; <https://en.wikipedia.org/wiki/Fisher-Yates_shuffle>.
 
 	* The resulting list has the same length and constituents as the original; only the order has changed.
 
@@ -64,14 +65,20 @@
 
 	* CAVEAT: because the selections are made non-destructively, duplicates may be returned; cf. 'shuffle'.
 -}
-generateSelection :: System.Random.RandomGen randomGen => randomGen -> [a] -> [a]
-generateSelection _ []		= error "ToolShed.System.Random.generateSelection:\tnull list"
-generateSelection _ [x]		= repeat x	-- Not strictly necessary, but more efficient.
-generateSelection randomGen l	= map (l !!) $ System.Random.randomRs (0, pred $ length l) randomGen
+generateSelection :: System.Random.RandomGen randomGen => randomGen -> [a] -> Maybe [a]
+generateSelection _ []		= Nothing
+generateSelection _ [x]		= Just $ repeat x	-- Not strictly necessary, but more efficient.
+generateSelection randomGen l	= Just . map (l !!) $ System.Random.randomRs (0, pred $ length l) randomGen
 
--- | Return a randomly selected element from the specified list.
-select :: System.Random.RandomGen randomGen => randomGen -> [a] -> a
-select randomGen	= head . generateSelection randomGen
+-- | Return a randomly selected element from those provided.
+select :: (
+	Data.Foldable.Foldable	foldable,
+	System.Random.RandomGen	randomGen
+ )
+	=> randomGen
+	-> foldable a
+	-> Maybe a
+select randomGen	= fmap head . generateSelection randomGen . Data.Foldable.toList
 
 {- |
 	* Generate an infinite list of data, each independently selected random instances of the specified /bounded/ type.
diff --git a/src-lib/ToolShed/Test/Ix.hs b/src-lib/ToolShed/Test/Ix.hs
new file mode 100644
--- /dev/null
+++ b/src-lib/ToolShed/Test/Ix.hs
@@ -0,0 +1,34 @@
+{-
+	Copyright (C) 2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Facilities testing of custom implementations of 'Data.Array.IArray.Ix'.
+-}
+
+module ToolShed.Test.Ix(
+-- * Functions
+-- ** Predicates
+	index
+) where
+
+import qualified	Data.Array.IArray
+
+-- | Checks that implementations of Data.Array.IArray.Ix satisfy rules.
+index :: (Bounded a, Data.Array.IArray.Ix a) => a -> Bool
+index x	= Data.Array.IArray.range (minBound, maxBound) !! Data.Array.IArray.index (minBound, maxBound) x == x
+
diff --git a/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Array.hs b/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Array.hs
--- a/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Array.hs
+++ b/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Array.hs
@@ -31,7 +31,12 @@
 import qualified	Data.Array.IArray
 import qualified	Test.QuickCheck
 
-instance (Bounded i, Data.Array.IArray.Ix i, Enum i, Test.QuickCheck.Arbitrary e) => Test.QuickCheck.Arbitrary (Data.Array.IArray.Array i e)	where
-	arbitrary	= (Data.Array.IArray.array bounds . zip [minBound .. maxBound]) `fmap` Test.QuickCheck.vector (succ $ fromEnum (snd bounds) - fromEnum (fst bounds))	where
+instance (
+	Bounded				i,
+	Data.Array.IArray.Ix		i,
+	Enum				i,
+	Test.QuickCheck.Arbitrary	e
+ ) => Test.QuickCheck.Arbitrary (Data.Array.IArray.Array i e)	where
+	arbitrary	= Data.Array.IArray.listArray bounds `fmap` Test.QuickCheck.vector (succ $ fromEnum (snd bounds) - fromEnum (fst bounds))	where
 		bounds	= (minBound, maxBound)
 
diff --git a/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Map.hs b/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Map.hs
--- a/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Map.hs
+++ b/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Map.hs
@@ -1,4 +1,5 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP #-}
 {-
 	Copyright (C) 2012-2015 Dr. Alistair Ward
 
@@ -18,16 +19,18 @@
 {- |
  [@AUTHOR@]	Dr. Alistair Ward
 
- [@DESCRIPTION@]	Implements 'Test.QuickCheck.Arbitrary' for 'Data.Map.Map'.
+ [@DESCRIPTION@]	Implements 'Test.QuickCheck.Arbitrary' for 'Data.Map.Map'; which was subsequently implemented in "QuickCheck-2.8.2".
 
  [@EXAMPLE@]	@Test.QuickCheck.sample (Test.QuickCheck.arbitrary :: Test.QuickCheck.Gen.Gen (Data.Map.Map Char Int))@
 -}
 
 module ToolShed.Test.QuickCheck.Arbitrary.Map() where
 
+#if !MIN_VERSION_QuickCheck(2,8,2)
 import qualified	Data.Map
 import qualified	Test.QuickCheck
 
 instance (Ord k, Test.QuickCheck.Arbitrary k, Test.QuickCheck.Arbitrary v) => Test.QuickCheck.Arbitrary (Data.Map.Map k v)	where
 	arbitrary	= Data.Map.fromList `fmap` Test.QuickCheck.arbitrary {-[(k, v)]-}
+#endif
 
diff --git a/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Set.hs b/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Set.hs
--- a/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Set.hs
+++ b/src-lib/ToolShed/Test/QuickCheck/Arbitrary/Set.hs
@@ -1,4 +1,5 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP #-}
 {-
 	Copyright (C) 2012-2015 Dr. Alistair Ward
 
@@ -18,16 +19,18 @@
 {- |
  [@AUTHOR@]	Dr. Alistair Ward
 
- [@DESCRIPTION@]	Implements 'Test.QuickCheck.Arbitrary' for 'Data.Set.Set'.
+ [@DESCRIPTION@]	Implements 'Test.QuickCheck.Arbitrary' for 'Data.Set.Set'; which was subsequently implemented in "QuickCheck-2.8.2".
 
  [@EXAMPLE@]	@Test.QuickCheck.sample (Test.QuickCheck.arbitrary :: Test.QuickCheck.Gen.Gen (Data.Set.Set Int))@
 -}
 
 module ToolShed.Test.QuickCheck.Arbitrary.Set() where
 
+#if !MIN_VERSION_QuickCheck(2,8,2)
 import qualified	Data.Set
 import qualified	Test.QuickCheck
 
 instance (Ord k, Test.QuickCheck.Arbitrary k) => Test.QuickCheck.Arbitrary (Data.Set.Set k)	where
 	arbitrary	= Data.Set.fromList `fmap` Test.QuickCheck.arbitrary {-[k]-}
+#endif
 
diff --git a/src-lib/ToolShed/Test/ReversibleIO.hs b/src-lib/ToolShed/Test/ReversibleIO.hs
--- a/src-lib/ToolShed/Test/ReversibleIO.hs
+++ b/src-lib/ToolShed/Test/ReversibleIO.hs
@@ -19,7 +19,7 @@
 
  [@DESCRIPTION@]
 
-	* Facilities testing of custom implementations of 'Read' & 'Show'.
+	* Facilitates testing of custom implementations of 'Read' & 'Show'.
 
 	* CAVEAT: it doesn't actually do any IO.
 -}
@@ -27,9 +27,32 @@
 module ToolShed.Test.ReversibleIO(
 -- * Functions
 -- ** Predicates
-	isReversible
+	isReversible,
+	readPrependedWhiteSpace,
+	readTrailingGarbage
 ) where
 
 -- | Checks that composing 'read' & 'show' is equivalent to the identity.
 isReversible :: (Eq r, Read r, Show r) => r -> Bool
 isReversible r	= read (show r) == r
+
+-- | Checks whether 'read' can skip prepended white space; 'isReversible' is a prerequisite.
+readPrependedWhiteSpace :: (Eq r, Read r, Show r) => r -> Bool
+readPrependedWhiteSpace r	= read (" \t\r\n" ++ show r) == r
+
+-- | Checks whether 'read' both copes with garbage following the valid input-data, & leaves it unchanged.
+readTrailingGarbage :: (
+	Eq	a,
+	Read	a,
+	Show	a
+ )
+	=> (Char -> Bool)	-- ^ Whether a character of garbage might reasonably be confused with valid data, & therefore should be dropped.
+	-> a			-- ^ The datum to be written & read.
+	-> String		-- ^ The text to follow the written datum.
+	-> Bool
+readTrailingGarbage predicate x s	= let
+	s'	= dropWhile predicate s
+ in case reads $ shows x s' of
+	[pair]	-> pair == (x, s')
+	_	-> False
+
diff --git a/src-test/Main.hs b/src-test/Main.hs
--- a/src-test/Main.hs
+++ b/src-test/Main.hs
@@ -24,35 +24,34 @@
 
 module Main(main) where
 
-import			Control.Arrow((***))
 import qualified	Control.Monad
+import qualified	Test.HUnit
 import qualified	System.Exit
-import qualified	ToolShed.Test.Data.Foldable		as Test.Data.Foldable
-import qualified	ToolShed.Test.Data.List			as Test.Data.List
-import qualified	ToolShed.Test.Data.List.Runlength	as Test.Data.List.Runlength
-import qualified	ToolShed.Test.Data.List.Splits		as Test.Data.List.Splits
-import qualified	ToolShed.Test.Data.Quadruple		as Test.Data.Quadruple
-import qualified	ToolShed.Test.Data.Triple		as Test.Data.Triple
-import qualified	ToolShed.Test.QuickCheck.Result		as Test.QuickCheck.Result
-import qualified	ToolShed.Test.SelfValidate		as Test.SelfValidate
-import qualified	ToolShed.Test.System.Random		as Test.System.Random
+import qualified	ToolShed.Test.HUnit.Data.List			as Test.HUnit.Data.List
+import qualified	ToolShed.Test.QuickCheck.Data.Foldable		as Test.QuickCheck.Data.Foldable
+import qualified	ToolShed.Test.QuickCheck.Data.List		as Test.QuickCheck.Data.List
+import qualified	ToolShed.Test.QuickCheck.Data.List.Runlength	as Test.QuickCheck.Data.List.Runlength
+import qualified	ToolShed.Test.QuickCheck.Data.List.Splits	as Test.QuickCheck.Data.List.Splits
+import qualified	ToolShed.Test.QuickCheck.Data.Quadruple		as Test.QuickCheck.Data.Quadruple
+import qualified	ToolShed.Test.QuickCheck.Data.Triple		as Test.QuickCheck.Data.Triple
+import qualified	ToolShed.Test.QuickCheck.Result			as Test.QuickCheck.Result
+import qualified	ToolShed.Test.QuickCheck.SelfValidate		as Test.QuickCheck.SelfValidate
+import qualified	ToolShed.Test.QuickCheck.System.Random		as Test.QuickCheck.System.Random
 
 -- | Entry-point.
 main :: IO ()
-main	= mapM_ (
-	snd {-exit-status-} . (
-		putStrLn . (++ ":") *** (
-			>>= (`Control.Monad.unless` System.Exit.exitFailure) . all Test.QuickCheck.Result.isSuccessful
-		)
-	)
+main	= mapM_ Test.HUnit.runTestTT [
+	Test.HUnit.Data.List.testCases
+ ] >> mapM_ (
+	(`Control.Monad.unless` System.Exit.exitFailure) . all Test.QuickCheck.Result.isSuccessful =<<
  ) [
-	("Data.Foldable",	Test.Data.Foldable.results),
-	("Data.List",		Test.Data.List.results),
-	("Data.List.Runlength",	Test.Data.List.Runlength.results),
-	("Data.List.Splits",	Test.Data.List.Splits.results),
-	("Data.Quadruple",	Test.Data.Quadruple.results),
-	("Data.Triple",		Test.Data.Triple.results),
-	("SelfValidate",	Test.SelfValidate.results),
-	("System.Random",	Test.System.Random.results)
+	Test.QuickCheck.Data.Foldable.results,
+	Test.QuickCheck.Data.List.results,
+	Test.QuickCheck.Data.List.Runlength.results,
+	Test.QuickCheck.Data.List.Splits.results,
+	Test.QuickCheck.Data.Quadruple.results,
+	Test.QuickCheck.Data.Triple.results,
+	Test.QuickCheck.SelfValidate.results,
+	Test.QuickCheck.System.Random.results
  ]
 
diff --git a/src-test/ToolShed/Test/Data/Foldable.hs b/src-test/ToolShed/Test/Data/Foldable.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/Data/Foldable.hs
+++ /dev/null
@@ -1,51 +0,0 @@
-{-
-	Copyright (C) 2012-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.Foldable".
--}
-
-module ToolShed.Test.Data.Foldable(
--- * Constants
-	results
-) where
-
-import qualified	Data.List
-import qualified	Data.Ord
-import qualified	Data.Set
-import qualified	ToolShed.Data.Foldable
-import qualified	ToolShed.Data.List
-import qualified	Test.QuickCheck
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= sequence [
-	Test.QuickCheck.quickCheckResult prop_gatherSet,
-	Test.QuickCheck.quickCheckResult prop_gatherBy
- ] where
-	prop_gatherSet :: Int -> Test.QuickCheck.Property
-	prop_gatherSet n	= Test.QuickCheck.label "prop_gatherSet" . (== l) . concat . ToolShed.Data.Foldable.gather $ Data.Set.fromDistinctAscList l	where
-		l	= [0 .. n `mod` 1024]
-
-	prop_gatherBy :: [Int] -> Test.QuickCheck.Property
-	prop_gatherBy l	= Test.QuickCheck.label "prop_gatherBy" $ map Data.List.sort (
-		ToolShed.Data.Foldable.gatherBy even l
-	 ) == (
-		map Data.List.sort . Data.List.groupBy (ToolShed.Data.List.equalityBy even) $ Data.List.sortBy (Data.Ord.comparing even) l
-	 )
-
diff --git a/src-test/ToolShed/Test/Data/List.hs b/src-test/ToolShed/Test/Data/List.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/Data/List.hs
+++ /dev/null
@@ -1,76 +0,0 @@
-{-
-	Copyright (C) 2012-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.List".
--}
-
-module ToolShed.Test.Data.List(
--- * Constants
-	results
-) where
-
-import qualified	Data.List
-import qualified	ToolShed.Data.List
-import qualified	Test.QuickCheck
-import			Test.QuickCheck((==>))
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= sequence [
-	Test.QuickCheck.quickCheckResult prop_chunk,
-	Test.QuickCheck.quickCheckResult prop_findConvergence,
-	Test.QuickCheck.quickCheckResult prop_linearise,
-	Test.QuickCheck.quickCheckResult prop_merge,
-	Test.QuickCheck.quickCheckResult prop_nub,
-	Test.QuickCheck.quickCheckResult prop_permutations,
-	Test.QuickCheck.quickCheckResult prop_permutations',
-	Test.QuickCheck.quickCheckResult prop_permutationsBy,
-	Test.QuickCheck.quickCheckResult prop_permutationsBy'
- ] where
-		prop_chunk :: Int -> [Int] -> Test.QuickCheck.Property
-		prop_chunk i l		= Test.QuickCheck.label "prop_chunk" $ concat (ToolShed.Data.List.chunk (succ $ abs i) l) == l
-
-		prop_findConvergence :: Int -> Test.QuickCheck.Property
-		prop_findConvergence	= Test.QuickCheck.label "prop_findConvergence" . (== 0) . ToolShed.Data.List.findConvergence . iterate (fst . (`quotRem` 2))
-
-		prop_linearise :: [(Int, Int)] -> Test.QuickCheck.Property
-		prop_linearise l	= Test.QuickCheck.label "prop_linearise" $ map (\[x, y] -> (x, y)) (ToolShed.Data.List.chunk 2 $ ToolShed.Data.List.linearise l) == l
-
-		prop_merge :: [Int] -> [Int] -> Test.QuickCheck.Property
-		prop_merge x y	= Test.QuickCheck.label "prop_merge" $ ToolShed.Data.List.merge (Data.List.sort x) (Data.List.sort y) == Data.List.sort (x ++ y)
-
-		prop_nub :: [Int] -> Test.QuickCheck.Property
-		prop_nub x	= Test.QuickCheck.label "prop_nub" $ ToolShed.Data.List.nub' x == Data.List.sort (Data.List.nub x)
-
-		prop_permutations, prop_permutations', prop_permutationsBy :: [[Int]] -> Test.QuickCheck.Property
-		prop_permutations l	= not (null l')	==> Test.QuickCheck.label "prop_permutations" $ length (ToolShed.Data.List.permutations l') == product (map length l')	where
-			l'	= take 6 $ map (take 6) l	-- Limit the task.
-
-		prop_permutations' l	= not (null l') && all (not . null) l'	==> Test.QuickCheck.label "prop_permutations'" . (== 1) . length . Data.List.nub . map length $ ToolShed.Data.List.permutations l'	where
-			l'	= take 7 $ map (take 5) l	-- Limit the task.
-
-		prop_permutationsBy l	= and [not $ null l', all (not . null) l', not $ null permutations]	==> Test.QuickCheck.label "prop_permutationsBy" . (== 1) . length . Data.List.nub $ map (length . Data.List.nub) permutations	where
-			l'		= take 8 $ map (take 4) l	-- Limit the task.
-			permutations	= ToolShed.Data.List.permutationsBy (/=) l'
-
-		prop_permutationsBy' :: Int -> Test.QuickCheck.Property
-		prop_permutationsBy' i	= Test.QuickCheck.label "prop_permutationsBy'" . all ((== range) . Data.List.sort) . ToolShed.Data.List.permutationsBy (/=) $ replicate (succ i') range	where
-			i'	= succ $ mod i 7
-			range	= [0 .. i']
-
diff --git a/src-test/ToolShed/Test/Data/List/Runlength.hs b/src-test/ToolShed/Test/Data/List/Runlength.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/Data/List/Runlength.hs
+++ /dev/null
@@ -1,36 +0,0 @@
-{-
-	Copyright (C) 2012-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.List.Runlength".
--}
-
-module ToolShed.Test.Data.List.Runlength(
--- * Constants
-	results
-) where
-
-import qualified	ToolShed.Data.List.Runlength
-import qualified	Test.QuickCheck
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= mapM Test.QuickCheck.quickCheckResult [prop_runLength] where
-	prop_runLength :: [Int] -> Test.QuickCheck.Property
-	prop_runLength l	= Test.QuickCheck.label "prop_runLength" $ ToolShed.Data.List.Runlength.decode (ToolShed.Data.List.Runlength.encode l) == l
-
diff --git a/src-test/ToolShed/Test/Data/List/Splits.hs b/src-test/ToolShed/Test/Data/List/Splits.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/Data/List/Splits.hs
+++ /dev/null
@@ -1,40 +0,0 @@
-{-
-	Copyright (C) 2012-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.List.Splits".
--}
-
-module ToolShed.Test.Data.List.Splits(
--- * Constants
-	results
-) where
-
-import			Control.Arrow((***))
-import qualified	Data.Tuple
-import qualified	ToolShed.Data.List.Splits
-import qualified	Test.QuickCheck
-import			Test.QuickCheck((==>))
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= mapM Test.QuickCheck.quickCheckResult [prop_splitsFrom] where
-	prop_splitsFrom :: Int -> [Int] -> Test.QuickCheck.Property
-	prop_splitsFrom i l	= not (null l) ==> Test.QuickCheck.label "prop_splitsFrom" $ take n (ToolShed.Data.List.Splits.splitsLeftFrom index l) == take n (map (Data.Tuple.swap . (reverse *** reverse)) . ToolShed.Data.List.Splits.splitsRightFrom (length l - index) $ reverse l)	where
-		index	= i `mod` length l
-		n	= succ index
diff --git a/src-test/ToolShed/Test/Data/Quadruple.hs b/src-test/ToolShed/Test/Data/Quadruple.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/Data/Quadruple.hs
+++ /dev/null
@@ -1,36 +0,0 @@
-{-
-	Copyright (C) 2013-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.Quadruple".
--}
-
-module ToolShed.Test.Data.Quadruple(
--- * Constants
-	results
-) where
-
-import qualified	Test.QuickCheck
-import qualified	ToolShed.Data.Quadruple
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= mapM Test.QuickCheck.quickCheckResult [prop_accessors]	where
-	prop_accessors :: (Int, Char, Bool, Float) -> Test.QuickCheck.Property
-	prop_accessors quadruple	= Test.QuickCheck.label "prop_accessors" $ (f ToolShed.Data.Quadruple.getFirst quadruple, f ToolShed.Data.Quadruple.getSecond quadruple, f ToolShed.Data.Quadruple.getThird quadruple, ToolShed.Data.Quadruple.getFourth quadruple) == quadruple	where
-		f	= ToolShed.Data.Quadruple.uncurry4 . ToolShed.Data.Quadruple.curry4
diff --git a/src-test/ToolShed/Test/Data/Triple.hs b/src-test/ToolShed/Test/Data/Triple.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/Data/Triple.hs
+++ /dev/null
@@ -1,37 +0,0 @@
-{-
-	Copyright (C) 2013-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.Triple".
--}
-
-module ToolShed.Test.Data.Triple(
--- * Constants
-	results
-) where
-
-import qualified	Test.QuickCheck
-import qualified	ToolShed.Data.Triple
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= mapM Test.QuickCheck.quickCheckResult [prop_accessors]	where
-	prop_accessors :: (Int, Char, Bool) -> Test.QuickCheck.Property
-	prop_accessors triple	= Test.QuickCheck.label "prop_accessors" $ (f ToolShed.Data.Triple.getFirst triple, f ToolShed.Data.Triple.getSecond triple, f ToolShed.Data.Triple.getThird triple) == triple	where
-		f	= ToolShed.Data.Triple.uncurry3 . ToolShed.Data.Triple.curry3
-
diff --git a/src-test/ToolShed/Test/HUnit/Data/List.hs b/src-test/ToolShed/Test/HUnit/Data/List.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/HUnit/Data/List.hs
@@ -0,0 +1,67 @@
+{-
+	Copyright (C) 2016 Dr. Alistair Ward
+
+	This file is part of ToolShed.
+
+	ToolShed is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	ToolShed is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with ToolShed.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]
+
+	* Static tests.
+
+	* <http://www.census.gov/srd/papers/pdf/rrs2006-02.pdf>
+-}
+
+module ToolShed.Test.HUnit.Data.List(
+-- * Constants
+	testCases
+-- * Functions
+--	approxDistance
+) where
+
+import qualified	Test.HUnit
+import			Test.HUnit((~:),(~?=))
+import qualified	ToolShed.Data.List	as Data.List
+
+approxDistance :: (String, String) -> Double
+approxDistance pair	= (/ fromIntegral precision) . fromInteger . round $ (fromIntegral precision * Data.List.measureJaroDistance pair :: Rational)	where
+	precision :: Int
+	precision	= 1000
+
+-- | Check the sanity of the implementation, by validating a list of static test-cases.
+testCases :: Test.HUnit.Test
+testCases	= Test.HUnit.test [
+	"ToolShed.Data.List.measureJaroDistance 1 failed." ~: Data.List.measureJaroDistance ("DIXON", "DICKSONX") ~?= (4 / 5 + 4 / 8 + 1 :: Rational) / 3,
+	"ToolShed.Data.List.measureJaroDistance 2 failed." ~: Data.List.measureJaroDistance ("JELLYFISH", "SMELLYFISH") ~?= (8 / 9 + 8 / 10 + 1 :: Rational) / 3,
+	"ToolShed.Data.List.measureJaroDistance 3 failed." ~: approxDistance ("SHACKLEFORD", "SHACKELFORD") ~?= 0.970,
+	"ToolShed.Data.List.measureJaroDistance 4 failed." ~: approxDistance ("DUNNINGHAM", "CUNNIGHAM") ~?= 0.896,
+	"ToolShed.Data.List.measureJaroDistance 5 failed." ~: approxDistance ("NICHLESON", "NICHULSON") ~?= 0.926,
+	"ToolShed.Data.List.measureJaroDistance 6 failed." ~: approxDistance ("JONES", "JOHNSON") ~?= 0.790,
+	"ToolShed.Data.List.measureJaroDistance 7 failed." ~: approxDistance ("MASSEY", "MASSIE") ~?= 0.889,
+	"ToolShed.Data.List.measureJaroDistance 8 failed." ~: approxDistance ("ABROMS", "ABRAMS") ~?= 0.889,
+	"ToolShed.Data.List.measureJaroDistance 9 failed." ~: Data.List.measureJaroDistance ("HARDIN", "MARTINEZ") ~?= (4 / 6 + 4 / 8 + 1 :: Rational) / 3,	-- CAVEAT: cited paper says this value should be zero ?!
+	"ToolShed.Data.List.measureJaroDistance 10 failed." ~: Data.List.measureJaroDistance ("ITMAN", "SMITH") ~?= (1 / 5 + 1 / 5 + 1 :: Rational) / 3,	-- CAVEAT: cited paper says this value should be zero ?!
+	"ToolShed.Data.List.measureJaroDistance 11 failed." ~: approxDistance ("JERALDINE", "GERALDINE") ~?= 0.926,
+	"ToolShed.Data.List.measureJaroDistance 12 failed." ~: approxDistance ("MARHTA", "MARTHA") ~?= 0.944,
+	"ToolShed.Data.List.measureJaroDistance 13 failed." ~: approxDistance ("MICHELLE", "MICHAEL") ~?= 0.869,
+	"ToolShed.Data.List.measureJaroDistance 14 failed." ~: approxDistance ("JULIES", "JULIUS") ~?= 0.889,
+	"ToolShed.Data.List.measureJaroDistance 15 failed." ~: approxDistance ("TANYA", "TONYA") ~?= 0.867,
+	"ToolShed.Data.List.measureJaroDistance 16 failed." ~: approxDistance ("DWAYNE", "DUANE") ~?= 0.822,
+	"ToolShed.Data.List.measureJaroDistance 17 failed." ~: approxDistance ("SEAN", "SUSAN") ~?= 0.783,
+	"ToolShed.Data.List.measureJaroDistance 18 failed." ~: approxDistance ("JON", "JOHN") ~?= 0.917,
+	"ToolShed.Data.List.measureJaroDistance 19 failed." ~: Data.List.measureJaroDistance ("JON", "JAN") ~?= (2 / 3 + 2 / 3 + 1 :: Rational) / 3	-- CAVEAT: cited paper says this value should be zero ?!
+ ]
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs b/src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs
@@ -0,0 +1,51 @@
+{-
+	Copyright (C) 2012-2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.Foldable".
+-}
+
+module ToolShed.Test.QuickCheck.Data.Foldable(
+-- * Constants
+	results
+) where
+
+import qualified	Data.List
+import qualified	Data.Ord
+import qualified	Data.Set
+import qualified	ToolShed.Data.Foldable
+import qualified	ToolShed.Data.List
+import qualified	Test.QuickCheck
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= sequence [
+	Test.QuickCheck.quickCheckResult prop_gatherSet,
+	Test.QuickCheck.quickCheckResult prop_gatherBy
+ ] where
+	prop_gatherSet :: Int -> Test.QuickCheck.Property
+	prop_gatherSet n	= Test.QuickCheck.label "prop_gatherSet" . (== l) . concat . ToolShed.Data.Foldable.gather $ Data.Set.fromDistinctAscList l	where
+		l	= [0 .. n `mod` 1024]
+
+	prop_gatherBy :: [Int] -> Test.QuickCheck.Property
+	prop_gatherBy l	= Test.QuickCheck.label "prop_gatherBy" $ map Data.List.sort (
+		ToolShed.Data.Foldable.gatherBy even l
+	 ) == (
+		map Data.List.sort . Data.List.groupBy (ToolShed.Data.List.equalityBy even) $ Data.List.sortBy (Data.Ord.comparing even) l
+	 )
+
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/List.hs b/src-test/ToolShed/Test/QuickCheck/Data/List.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/Data/List.hs
@@ -0,0 +1,91 @@
+{-
+	Copyright (C) 2012-2016 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.List".
+-}
+
+module ToolShed.Test.QuickCheck.Data.List(
+-- * Constants
+	results
+) where
+
+import qualified	Data.List
+import qualified	Data.Tuple
+import qualified	ToolShed.Data.List
+import qualified	Test.QuickCheck
+import			Test.QuickCheck((==>))
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= sequence [
+	Test.QuickCheck.quickCheckResult prop_chunk,
+	Test.QuickCheck.quickCheckResult prop_findConvergence,
+	Test.QuickCheck.quickCheckResult prop_linearise,
+	Test.QuickCheck.quickCheckResult prop_merge,
+	Test.QuickCheck.quickCheckResult prop_nub,
+	Test.QuickCheck.quickCheckResult prop_permutations,
+	Test.QuickCheck.quickCheckResult prop_permutations',
+	Test.QuickCheck.quickCheckResult prop_permutationsBy,
+	Test.QuickCheck.quickCheckResult prop_permutationsBy',
+	Test.QuickCheck.quickCheckResult prop_interleave,
+	Test.QuickCheck.quickCheckResult prop_interleave',
+	Test.QuickCheck.quickCheckResult prop_jaroDistanceCommutative,
+	Test.QuickCheck.quickCheckResult prop_jaroDistanceRange
+ ] where
+		prop_chunk :: Int -> [Int] -> Test.QuickCheck.Property
+		prop_chunk i l		= Test.QuickCheck.label "prop_chunk" $ concat (ToolShed.Data.List.chunk (succ $ abs i) l) == l
+
+		prop_findConvergence :: Int -> Test.QuickCheck.Property
+		prop_findConvergence	= Test.QuickCheck.label "prop_findConvergence" . (== 0) . ToolShed.Data.List.findConvergence . iterate (fst . (`quotRem` 2))
+
+		prop_linearise :: [(Int, Int)] -> Test.QuickCheck.Property
+		prop_linearise l	= Test.QuickCheck.label "prop_linearise" $ map (\[x, y] -> (x, y)) (ToolShed.Data.List.chunk 2 $ ToolShed.Data.List.linearise l) == l
+
+		prop_merge :: [Int] -> [Int] -> Test.QuickCheck.Property
+		prop_merge x y	= Test.QuickCheck.label "prop_merge" $ ToolShed.Data.List.merge (Data.List.sort x) (Data.List.sort y) == Data.List.sort (x ++ y)
+
+		prop_nub :: [Int] -> Test.QuickCheck.Property
+		prop_nub x	= Test.QuickCheck.label "prop_nub" $ ToolShed.Data.List.nub' x == Data.List.sort (Data.List.nub x)
+
+		prop_permutations, prop_permutations', prop_permutationsBy :: [[Int]] -> Test.QuickCheck.Property
+		prop_permutations l	= not (null l')	==> Test.QuickCheck.label "prop_permutations" $ length (ToolShed.Data.List.permutations l') == product (map length l')	where
+			l'	= take 6 $ map (take 6) l	-- Limit the task.
+
+		prop_permutations' l	= not (null l') && all (not . null) l'	==> Test.QuickCheck.label "prop_permutations'" . (== 1) . length . Data.List.nub . map length $ ToolShed.Data.List.permutations l'	where
+			l'	= take 7 $ map (take 5) l	-- Limit the task.
+
+		prop_permutationsBy l	= and [not $ null l', all (not . null) l', not $ null permutations]	==> Test.QuickCheck.label "prop_permutationsBy" . (== 1) . length . Data.List.nub $ map (length . Data.List.nub) permutations	where
+			l'		= take 8 $ map (take 4) l	-- Limit the task.
+			permutations	= ToolShed.Data.List.permutationsBy (/=) l'
+
+		prop_permutationsBy' :: Int -> Test.QuickCheck.Property
+		prop_permutationsBy' i	= Test.QuickCheck.label "prop_permutationsBy'" . all ((== range) . Data.List.sort) . ToolShed.Data.List.permutationsBy (/=) $ replicate (succ i') range	where
+			i'	= succ $ mod i 7
+			range	= [0 .. i']
+
+		prop_interleave :: [Int] -> [Int] -> Test.QuickCheck.Property
+		prop_interleave xs ys	= Test.QuickCheck.label "prop_interleave" $ length (ToolShed.Data.List.interleave xs ys) == length xs + length ys
+
+		prop_interleave' :: [Int] -> [Int] -> Test.QuickCheck.Property
+		prop_interleave' xs ys	= not (null xs) ==> Test.QuickCheck.label "prop_interleave'" $ head (ToolShed.Data.List.interleave xs ys) == head xs
+
+		prop_jaroDistanceCommutative, prop_jaroDistanceRange :: (String, String) -> Test.QuickCheck.Property
+		prop_jaroDistanceCommutative pair	= Test.QuickCheck.label "prop_jaroDistanceCommutative" $ (ToolShed.Data.List.measureJaroDistance pair :: Rational) == ToolShed.Data.List.measureJaroDistance (Data.Tuple.swap pair)
+		prop_jaroDistanceRange pair		= Test.QuickCheck.label "prop_jaroDistanceRange" $ all ($ (ToolShed.Data.List.measureJaroDistance pair :: Rational)) [(>= 0), (<= 1)]
+
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/List/Runlength.hs b/src-test/ToolShed/Test/QuickCheck/Data/List/Runlength.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/Data/List/Runlength.hs
@@ -0,0 +1,36 @@
+{-
+	Copyright (C) 2012-2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.List.Runlength".
+-}
+
+module ToolShed.Test.QuickCheck.Data.List.Runlength(
+-- * Constants
+	results
+) where
+
+import qualified	ToolShed.Data.List.Runlength
+import qualified	Test.QuickCheck
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= mapM Test.QuickCheck.quickCheckResult [prop_runLength] where
+	prop_runLength :: [Int] -> Test.QuickCheck.Property
+	prop_runLength l	= Test.QuickCheck.label "prop_runLength" $ ToolShed.Data.List.Runlength.decode (ToolShed.Data.List.Runlength.encode l) == l
+
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/List/Splits.hs b/src-test/ToolShed/Test/QuickCheck/Data/List/Splits.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/Data/List/Splits.hs
@@ -0,0 +1,40 @@
+{-
+	Copyright (C) 2012-2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.List.Splits".
+-}
+
+module ToolShed.Test.QuickCheck.Data.List.Splits(
+-- * Constants
+	results
+) where
+
+import			Control.Arrow((***))
+import qualified	Data.Tuple
+import qualified	ToolShed.Data.List.Splits
+import qualified	Test.QuickCheck
+import			Test.QuickCheck((==>))
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= mapM Test.QuickCheck.quickCheckResult [prop_splitsFrom] where
+	prop_splitsFrom :: Int -> [Int] -> Test.QuickCheck.Property
+	prop_splitsFrom i l	= not (null l) ==> Test.QuickCheck.label "prop_splitsFrom" $ take n (ToolShed.Data.List.Splits.splitsLeftFrom index l) == take n (map (Data.Tuple.swap . (reverse *** reverse)) . ToolShed.Data.List.Splits.splitsRightFrom (length l - index) $ reverse l)	where
+		index	= i `mod` length l
+		n	= succ index
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs b/src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs
@@ -0,0 +1,36 @@
+{-
+	Copyright (C) 2013-2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.Quadruple".
+-}
+
+module ToolShed.Test.QuickCheck.Data.Quadruple(
+-- * Constants
+	results
+) where
+
+import qualified	Test.QuickCheck
+import qualified	ToolShed.Data.Quadruple
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= mapM Test.QuickCheck.quickCheckResult [prop_accessors]	where
+	prop_accessors :: (Int, Char, Bool, Float) -> Test.QuickCheck.Property
+	prop_accessors quadruple	= Test.QuickCheck.label "prop_accessors" $ (f ToolShed.Data.Quadruple.getFirst quadruple, f ToolShed.Data.Quadruple.getSecond quadruple, f ToolShed.Data.Quadruple.getThird quadruple, ToolShed.Data.Quadruple.getFourth quadruple) == quadruple	where
+		f	= ToolShed.Data.Quadruple.uncurry4 . ToolShed.Data.Quadruple.curry4
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/Triple.hs b/src-test/ToolShed/Test/QuickCheck/Data/Triple.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/Data/Triple.hs
@@ -0,0 +1,37 @@
+{-
+	Copyright (C) 2013-2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.Data.Triple".
+-}
+
+module ToolShed.Test.QuickCheck.Data.Triple(
+-- * Constants
+	results
+) where
+
+import qualified	Test.QuickCheck
+import qualified	ToolShed.Data.Triple
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= mapM Test.QuickCheck.quickCheckResult [prop_accessors]	where
+	prop_accessors :: (Int, Char, Bool) -> Test.QuickCheck.Property
+	prop_accessors triple	= Test.QuickCheck.label "prop_accessors" $ (f ToolShed.Data.Triple.getFirst triple, f ToolShed.Data.Triple.getSecond triple, f ToolShed.Data.Triple.getThird triple) == triple	where
+		f	= ToolShed.Data.Triple.uncurry3 . ToolShed.Data.Triple.curry3
+
diff --git a/src-test/ToolShed/Test/QuickCheck/SelfValidate.hs b/src-test/ToolShed/Test/QuickCheck/SelfValidate.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/SelfValidate.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE CPP #-}
+{-
+	Copyright (C) 2012-2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.SelfValidate".
+-}
+
+module ToolShed.Test.QuickCheck.SelfValidate(
+-- * Constants
+	results,
+-- * Types
+-- ** Data-types
+--	Primes
+) where
+
+import qualified	Data.Foldable
+import qualified	Data.List
+import qualified	Data.Map
+import qualified	Data.Set
+import qualified	Test.QuickCheck
+import			Test.QuickCheck((==>))
+import qualified	ToolShed.SelfValidate	as SelfValidate
+
+#if !MIN_VERSION_QuickCheck(2,8,2)
+import			ToolShed.Test.QuickCheck.Arbitrary.Map()
+import			ToolShed.Test.QuickCheck.Arbitrary.Set()
+#endif
+
+-- | A test-type.
+newtype Primes	= MkPrimes Int	deriving (Eq, Ord, Show)
+
+instance SelfValidate.SelfValidator Primes	where
+	getErrors (MkPrimes i)	= SelfValidate.extractErrors [
+		(any ((== 0) . (i `rem`)) [2,3,5],	"Composite; " ++ show i),
+		(i < 0,					"Negative; " ++ show i),
+		(i `elem` [0, 1],			"Excluded; " ++ show i)
+	 ]
+
+instance Test.QuickCheck.Arbitrary Primes	where
+	arbitrary	= MkPrimes `fmap` Test.QuickCheck.elements [negate limit .. limit]	where limit = pred $ 7 * 7
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= sequence [
+	Test.QuickCheck.quickCheckResult prop_list,
+	Test.QuickCheck.quickCheckResult prop_list',
+	Test.QuickCheck.quickCheckResult prop_set,
+	Test.QuickCheck.quickCheckResult prop_map
+ ] where
+		prop_list, prop_list' :: [Primes] -> Test.QuickCheck.Property
+		prop_list l	= not (null l) ==> Test.QuickCheck.label "prop_list" $ SelfValidate.getErrors (head l) `Data.List.isPrefixOf` SelfValidate.getErrors l
+		prop_list' l	= Test.QuickCheck.label "prop_list'" $ all (
+			(`elem` map SelfValidate.getErrors l) . SelfValidate.getErrors
+		 ) l
+
+		prop_set :: Data.Set.Set Primes -> Test.QuickCheck.Property
+		prop_set s	= Test.QuickCheck.label "prop_set" $ Data.Foldable.all (
+			(`Data.Set.isSubsetOf` Data.Set.fromList (SelfValidate.getErrors s)) . Data.Set.fromList . SelfValidate.getErrors
+		 ) s
+
+		prop_map :: Data.Map.Map Int Primes -> Test.QuickCheck.Property
+		prop_map m	= Test.QuickCheck.label "prop_map" $ Data.Foldable.all (
+			(`Data.Set.isSubsetOf` Data.Set.fromList (SelfValidate.getErrors m)) . Data.Set.fromList . SelfValidate.getErrors
+		 ) m
+
diff --git a/src-test/ToolShed/Test/QuickCheck/System/Random.hs b/src-test/ToolShed/Test/QuickCheck/System/Random.hs
new file mode 100644
--- /dev/null
+++ b/src-test/ToolShed/Test/QuickCheck/System/Random.hs
@@ -0,0 +1,83 @@
+{-
+	Copyright (C) 2013-2015 Dr. Alistair Ward
+
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-}
+{- |
+ [@AUTHOR@]	Dr. Alistair Ward
+
+ [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.System.Random".
+-}
+
+module ToolShed.Test.QuickCheck.System.Random(
+-- * Constants
+	results,
+-- * Functions
+--	getMean,
+--	getStandardDeviation
+) where
+
+import qualified	Control.Arrow
+import			Control.Arrow((&&&),(***))
+import qualified	Data.Foldable
+import qualified	Data.List
+import qualified	Data.Map
+import qualified	System.Random
+import qualified	Test.QuickCheck
+import qualified	ToolShed.System.Random
+
+-- | Determines the /mean/ of the specified numbers
+getMean :: (Data.Foldable.Foldable foldable, Real r, Fractional result) => foldable r -> result
+getMean	= uncurry (/) . (realToFrac *** fromIntegral) . Data.Foldable.foldr (\i -> (+ i) *** succ) (0, 0 :: Int)
+
+-- | Find the standard-deviation of the specified list.
+getStandardDeviation :: (Data.Foldable.Foldable foldable, Functor foldable, Real r) => foldable r -> Double
+getStandardDeviation x	= sqrt . getMean $ fmap ((^ (2 :: Int)) . (+ negate (getMean x :: Rational)) . toRational) x
+
+-- | The constant test-results for this data-type.
+results :: IO [Test.QuickCheck.Result]
+results	= sequence [
+	Test.QuickCheck.quickCheckResult prop_shuffle,
+	Test.QuickCheck.quickCheckResult prop_shuffleDistribution
+ ] where
+		prop_shuffle :: Int -> Int -> Test.QuickCheck.Property
+		prop_shuffle seed l	= Test.QuickCheck.label "prop_shuffle" . (== testList) . Data.List.sort $ ToolShed.System.Random.shuffle (System.Random.mkStdGen seed) testList	where
+			testList	= [0 .. l `mod` 10000]
+
+		prop_shuffleDistribution :: Int -> Test.QuickCheck.Property
+		prop_shuffleDistribution	= Test.QuickCheck.label "prop_shuffleDistribution" . all (
+			uncurry (&&) . (
+				(
+					< recip 16 {-empirically-}	-- The ideal value for a uniform distribution, would be zero.
+				) . (
+					/ getStandardDeviation (populationSize : replicate (pred $ length testList) 0)	-- Normalise wrt the worst-case; which occurs when this column contains the same letter, for each test-case in the population.
+				) . getStandardDeviation &&& (
+					== populationSize	-- Confirm the size of the test-data.
+				) . Data.Foldable.sum
+			)
+		 ) . map (
+			foldr (
+				uncurry $ Data.Map.insertWith (+)
+			) (
+				Data.Map.fromList . zip testList $ repeat (0 :: Int)	-- Initial value.
+			) . (`zip` repeat 1)	-- Count the instances of each letter in this column, which for a uniform distribution, should be approximately the same.
+		 ) . Data.List.transpose {-examine the columns-} . take populationSize . map fst {-shuffled digits-} . tail {-drop initial value-} . iterate (
+			Control.Arrow.first (`ToolShed.System.Random.shuffle` testList) . System.Random.split . snd
+		 ) . (,) undefined . System.Random.mkStdGen	where
+			testList :: String
+			testList	= ['a' .. 'z']
+
+			populationSize :: Int
+			populationSize	= 1000
+
diff --git a/src-test/ToolShed/Test/SelfValidate.hs b/src-test/ToolShed/Test/SelfValidate.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/SelfValidate.hs
+++ /dev/null
@@ -1,77 +0,0 @@
-{-
-	Copyright (C) 2012-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.SelfValidate".
--}
-
-module ToolShed.Test.SelfValidate(
--- * Constants
-	results,
--- * Types
--- ** Data-types
---	Primes
-) where
-
-import qualified	Data.Foldable
-import qualified	Data.List
-import qualified	Data.Map
-import qualified	Data.Set
-import qualified	Test.QuickCheck
-import			Test.QuickCheck((==>))
-import qualified	ToolShed.SelfValidate	as SelfValidate
-import			ToolShed.Test.QuickCheck.Arbitrary.Map()
-import			ToolShed.Test.QuickCheck.Arbitrary.Set()
-
--- | A test-type.
-newtype Primes	= MkPrimes Int	deriving (Eq, Ord, Show)
-
-instance SelfValidate.SelfValidator Primes	where
-	getErrors (MkPrimes i)	= SelfValidate.extractErrors [
-		(any ((== 0) . (i `rem`)) [2,3,5],	"Composite; " ++ show i),
-		(i < 0,					"Negative; " ++ show i),
-		(i `elem` [0, 1],			"Excluded; " ++ show i)
-	 ]
-
-instance Test.QuickCheck.Arbitrary Primes	where
-	arbitrary	= MkPrimes `fmap` Test.QuickCheck.elements [negate limit .. limit]	where limit = pred $ 7 * 7
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= sequence [
-	Test.QuickCheck.quickCheckResult prop_list,
-	Test.QuickCheck.quickCheckResult prop_list',
-	Test.QuickCheck.quickCheckResult prop_set,
-	Test.QuickCheck.quickCheckResult prop_map
- ] where
-		prop_list, prop_list' :: [Primes] -> Test.QuickCheck.Property
-		prop_list l	= not (null l) ==> Test.QuickCheck.label "prop_list" $ SelfValidate.getErrors (head l) `Data.List.isPrefixOf` SelfValidate.getErrors l
-		prop_list' l	= Test.QuickCheck.label "prop_list'" $ all (
-			(`elem` map SelfValidate.getErrors l) . SelfValidate.getErrors
-		 ) l
-
-		prop_set :: Data.Set.Set Primes -> Test.QuickCheck.Property
-		prop_set s	= Test.QuickCheck.label "prop_set" $ Data.Foldable.all (
-			(`Data.Set.isSubsetOf` Data.Set.fromList (SelfValidate.getErrors s)) . Data.Set.fromList . SelfValidate.getErrors
-		 ) s
-
-		prop_map :: Data.Map.Map Int Primes -> Test.QuickCheck.Property
-		prop_map m	= Test.QuickCheck.label "prop_map" $ Data.Foldable.all (
-			(`Data.Set.isSubsetOf` Data.Set.fromList (SelfValidate.getErrors m)) . Data.Set.fromList . SelfValidate.getErrors
-		 ) m
-
diff --git a/src-test/ToolShed/Test/System/Random.hs b/src-test/ToolShed/Test/System/Random.hs
deleted file mode 100644
--- a/src-test/ToolShed/Test/System/Random.hs
+++ /dev/null
@@ -1,83 +0,0 @@
-{-
-	Copyright (C) 2013-2015 Dr. Alistair Ward
-
-	This program is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program.  If not, see <http://www.gnu.org/licenses/>.
--}
-{- |
- [@AUTHOR@]	Dr. Alistair Ward
-
- [@DESCRIPTION@]	Defines /QuickCheck/-properties "ToolShed.System.Random".
--}
-
-module ToolShed.Test.System.Random(
--- * Constants
-	results,
--- * Functions
---	getMean,
---	getStandardDeviation
-) where
-
-import qualified	Control.Arrow
-import			Control.Arrow((&&&),(***))
-import qualified	Data.Foldable
-import qualified	Data.List
-import qualified	Data.Map
-import qualified	System.Random
-import qualified	Test.QuickCheck
-import qualified	ToolShed.System.Random
-
--- | Determines the /mean/ of the specified numbers
-getMean :: (Data.Foldable.Foldable f, Real r, Fractional result) => f r -> result
-getMean	= uncurry (/) . (realToFrac *** fromIntegral) . Data.Foldable.foldr (\i -> (+ i) *** succ) (0, 0 :: Int)
-
--- | Find the standard-deviation of the specified list.
-getStandardDeviation :: (Data.Foldable.Foldable f, Functor f, Real r) => f r -> Double
-getStandardDeviation x	= sqrt . getMean $ fmap ((^ (2 :: Int)) . (+ negate (getMean x :: Rational)) . toRational) x
-
--- | The constant test-results for this data-type.
-results :: IO [Test.QuickCheck.Result]
-results	= sequence [
-	Test.QuickCheck.quickCheckResult prop_shuffle,
-	Test.QuickCheck.quickCheckResult prop_shuffleDistribution
- ] where
-		prop_shuffle :: Int -> Int -> Test.QuickCheck.Property
-		prop_shuffle seed l	= Test.QuickCheck.label "prop_shuffle" . (== testList) . Data.List.sort $ ToolShed.System.Random.shuffle (System.Random.mkStdGen seed) testList	where
-			testList	= [0 .. l `mod` 10000]
-
-		prop_shuffleDistribution :: Int -> Test.QuickCheck.Property
-		prop_shuffleDistribution	= Test.QuickCheck.label "prop_shuffleDistribution" . all (
-			uncurry (&&) . (
-				(
-					< recip 20 {-empirically-}	-- The ideal value for a uniform distribution, would be zero.
-				) . (
-					/ getStandardDeviation (populationSize : replicate (pred $ length testList) 0)	-- Normalise wrt the worst-case; which occurs when this column contains the same letter, for each test-case in the population.
-				) . getStandardDeviation &&& (
-					== populationSize	-- Confirm the size of the test-data.
-				) . Data.Foldable.sum
-			)
-		 ) . map (
-			foldr (
-				uncurry $ Data.Map.insertWith (+)
-			) (
-				Data.Map.fromList . zip testList $ repeat (0 :: Int)	-- Initial value.
-			) . (`zip` repeat 1)	-- Count the instances of each letter in this column, which for a uniform distribution, should be approximately the same.
-		 ) . Data.List.transpose {-examine the columns-} . take populationSize . map fst {-shuffled digits-} . tail {-drop initial value-} . iterate (
-			Control.Arrow.first (`ToolShed.System.Random.shuffle` testList) . System.Random.split . snd
-		 ) . (,) undefined . System.Random.mkStdGen	where
-			testList :: String
-			testList	= ['a' .. 'z']
-
-			populationSize :: Int
-			populationSize	= 1000
-
diff --git a/toolshed.cabal b/toolshed.cabal
--- a/toolshed.cabal
+++ b/toolshed.cabal
@@ -14,7 +14,7 @@
 -- along with ToolShed.  If not, see <http://www.gnu.org/licenses/>.
 
 Name:		toolshed
-Version:	0.16.0.0
+Version:	0.17.0.2
 Cabal-version:	>= 1.10
 Copyright:	(C) 2010-2015 Dr. Alistair Ward
 License:	GPL
@@ -25,17 +25,22 @@
 Build-type:	Simple
 Description:	Ill-defined unrelated utilities used by other packages from <http://functionalley.eu>
 Category:	Utils
-Tested-with:	GHC == 7.4, GHC == 7.6, GHC == 7.8, GHC == 7.10
+Tested-with:	GHC == 7.4, GHC == 7.6, GHC == 7.10.1, GHC == 8.0.1
 Homepage:	http://functionalley.eu
-Maintainer:	mailto <colon> toolshed <at> functionalley <dot> eu
-Bug-reports:	mailto <colon> toolshed <at> functionalley <dot> eu
+Maintainer:	mailto:toolshed@functionalley.eu
+Bug-reports:	mailto:toolshed@functionalley.eu
 
 -- None of these files are needed at run-time.
 Extra-source-files:
+    .ghci
     changelog.markdown
     copyright
     README.markdown
 
+source-repository head
+    type:	git
+    location:	https://github.com/functionalley/ToolShed
+
 -- Enable using: 'cabal configure -f llvm'.
 flag llvm
     Description:	Whether the 'llvm' compiler-backend has been installed and is required for code-generation.
@@ -44,24 +49,26 @@
 
 Library
     Default-language:	Haskell2010
-    GHC-options:	-Wall -O2 -fno-warn-tabs
+    GHC-options:	-O2 -Wall -fno-warn-tabs
     Hs-source-dirs:	src-lib
 
     Exposed-modules:
         ToolShed.Data.Foldable
+        ToolShed.Data.Array.IArray
         ToolShed.Data.List
         ToolShed.Data.List.Runlength
         ToolShed.Data.List.Splits
         ToolShed.Data.Pair
         ToolShed.Data.Quadruple
+        ToolShed.Data.String
         ToolShed.Data.Triple
-        ToolShed.Defaultable
         ToolShed.Options
         ToolShed.SelfValidate
         ToolShed.System.File
         ToolShed.System.Random
         ToolShed.System.TimeAction
         ToolShed.System.TimePure
+        ToolShed.Test.Ix
         ToolShed.Test.QuickCheck.Arbitrary.Array
         ToolShed.Test.QuickCheck.Arbitrary.Map
         ToolShed.Test.QuickCheck.Arbitrary.Set
@@ -74,6 +81,7 @@
         array,
         base == 4.*,
         containers >= 0.4.2.0,
+        data-default,
         deepseq >= 1.1,
         directory,
         filepath,
@@ -81,14 +89,14 @@
         random
 
     if impl(ghc >= 7.4.1)
-        GHC-prof-options:	-prof -fprof-auto -fprof-cafs
+        GHC-prof-options:	-fprof-auto -fprof-cafs
     else
-        GHC-prof-options:	-prof -auto-all -caf-all
+        GHC-prof-options:	-auto-all -caf-all
 
     if impl(ghc >= 7.0) && flag(llvm)
         GHC-options:	-fllvm
 
-Test-Suite quickCheck
+Test-Suite test
     Default-language:	Haskell2010
     GHC-options:	-Wall -fno-warn-tabs
     Hs-source-dirs:	src-test
@@ -97,20 +105,21 @@
 
 -- Required for 'cabal sdist'.
     Other-modules:
-        ToolShed.Test.Data.Foldable
-        ToolShed.Test.Data.List
-        ToolShed.Test.Data.List.Runlength
-        ToolShed.Test.Data.List.Splits
-        ToolShed.Test.Data.Quadruple
-        ToolShed.Test.Data.Triple
-        ToolShed.Test.SelfValidate
-        ToolShed.Test.System.Random
+        ToolShed.Test.HUnit.Data.List
+        ToolShed.Test.QuickCheck.Data.Foldable
+        ToolShed.Test.QuickCheck.Data.List
+        ToolShed.Test.QuickCheck.Data.List.Runlength
+        ToolShed.Test.QuickCheck.Data.List.Splits
+        ToolShed.Test.QuickCheck.Data.Quadruple
+        ToolShed.Test.QuickCheck.Data.Triple
+        ToolShed.Test.QuickCheck.SelfValidate
+        ToolShed.Test.QuickCheck.System.Random
 
     Build-depends:
         base == 4.*,
         containers >= 0.4.2.0,
+        HUnit,
         QuickCheck >= 2.2,
         random,
         toolshed
-
 
