diff --git a/.ghci b/.ghci
--- a/.ghci
+++ b/.ghci
@@ -1,1 +1,1 @@
-:set -isrc-lib:src-test:dist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h
+:set -isrc-lib:src-test:dist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h -Wall -fno-warn-tabs
diff --git a/changelog.markdown b/changelog.markdown
--- a/changelog.markdown
+++ b/changelog.markdown
@@ -125,7 +125,14 @@
 * 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.
+
+## 0.18.0.0
+* Removed single-function module **ToolShed.Data.Array.IArray**.
+* Refactoring of **ToolShed.Data.Foldable.hasDuplicates**, for which quickchecks were then added.
+* Added mutators to **ToolShed.Data.Triple** & **ToolShed.Data.Quadruple**.
diff --git a/src-lib/ToolShed/Data/Array/IArray.hs b/src-lib/ToolShed/Data/Array/IArray.hs
deleted file mode 100644
--- a/src-lib/ToolShed/Data/Array/IArray.hs
+++ /dev/null
@@ -1,47 +0,0 @@
-{-
-	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
@@ -31,11 +31,14 @@
 import			Control.Arrow((&&&))
 import qualified	Data.Foldable
 import qualified	Data.Map
+import qualified	Data.Set
 
 {- |
 	* Group equal (though not necessarily adjacent; cf. 'Data.List.groupBy') elements, according to the specified comparator.
 
 	* The groups are returned in ascending order, whilst their elements remain in their original order.
+
+	* See 'GHC.Exts.groupWith', 'Data.List.Extra.groupSortOn'.
 -}
 gatherBy
 	:: (Data.Foldable.Foldable foldable, Ord b)
@@ -48,7 +51,15 @@
 gather :: (Data.Foldable.Foldable foldable, Ord a) => foldable a -> [[a]]
 gather	= gatherBy id
 
--- | Whether the specified collection contains any equal items.
+{- |
+	* Whether the specified collection contains any equal items.
+
+	* See 'Data.List.Extra.anySame'.
+-}
 hasDuplicates :: (Data.Foldable.Foldable foldable, Ord a) => foldable a -> Bool
-hasDuplicates	= any ((> 1) . length) . gather
+hasDuplicates	= fst . Data.Foldable.foldr (
+	\x (result, s)	-> if result || Data.Set.member x s
+		then (True, s)
+		else (False, Data.Set.insert x s)
+ ) (False, Data.Set.empty)
 
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
@@ -64,6 +64,8 @@
 	* If the chunk-length is zero, the resulting list will be an infinite sequence of null lists.
 
 	* CAVEAT: a similar function is available in the module /Data.List.Split/, though this one checks for @(chunkLength < 0)@.
+
+	* See 'Data.List.Extra.chunksOf'.
 -}
 chunk
 	:: ChunkLength
@@ -94,8 +96,8 @@
 
 -- | Take the first element from the (potentially infinite) list, which matches the subsequent element, according to the specified function.
 findConvergenceBy :: Matches a -> [a] -> a
-findConvergenceBy _ []	=  error "ToolShed.Data.List.findConvergenceBy:\ta null list is too short for convergence to exist"
-findConvergenceBy _ [_]	=  error "ToolShed.Data.List.findConvergenceBy:\ta singleton list is too short for convergence to exist"
+findConvergenceBy _ []	= error "ToolShed.Data.List.findConvergenceBy:\ta null list is too short for convergence to exist"
+findConvergenceBy _ [_]	= error "ToolShed.Data.List.findConvergenceBy:\ta singleton list is too short for convergence to exist"
 findConvergenceBy matches l
 	| null l'	= error "ToolShed.Data.List.findConvergenceBy:\tno convergence found"
 	| otherwise	= fst $ head l'
@@ -140,6 +142,8 @@
 	* CAVEAT: the specified list must be finite, since the entire set is constructed before streaming to a list.
 
 	* CAVEAT: it sorts the output as a side-effect, & consequently it requires a type which implements 'Ord'.
+
+	* See 'Data.List.Extra.nubOrd'.
 -}
 nub' :: Ord a => [a] -> [a]
 nub'	= Data.Set.toList . Data.Set.fromList
diff --git a/src-lib/ToolShed/Data/Quadruple.hs b/src-lib/ToolShed/Data/Quadruple.hs
--- a/src-lib/ToolShed/Data/Quadruple.hs
+++ b/src-lib/ToolShed/Data/Quadruple.hs
@@ -30,7 +30,12 @@
 	getFirst,
 	getSecond,
 	getThird,
-	getFourth
+	getFourth,
+-- ** Mutators
+	mutateFirst,
+	mutateSecond,
+	mutateThird,
+	mutateForth
 ) where
 
 -- | Extends the concept of 'Data.Tuple.curry'.
@@ -57,3 +62,19 @@
 getFourth :: (a, b, c, d) -> d
 getFourth (_, _, _, d)	= d
 
+
+-- | Operate on first datum.
+mutateFirst :: (a -> a') -> (a, b, c, d) -> (a', b, c, d)
+mutateFirst f (a, b, c, d)	= (f a, b, c, d)
+
+-- | Operate on second datum.
+mutateSecond :: (b -> b') -> (a, b, c, d) -> (a, b', c, d)
+mutateSecond f (a, b, c, d)	= (a, f b, c, d)
+
+-- | Operate on third datum.
+mutateThird :: (c -> c') -> (a, b, c, d) -> (a, b, c', d)
+mutateThird f (a, b, c, d)	= (a, b, f c, d)
+
+-- | Operate on third datum.
+mutateForth :: (d -> d') -> (a, b, c, d) -> (a, b, c, d')
+mutateForth f (a, b, c, d)	= (a, b, c, f d)
diff --git a/src-lib/ToolShed/Data/Triple.hs b/src-lib/ToolShed/Data/Triple.hs
--- a/src-lib/ToolShed/Data/Triple.hs
+++ b/src-lib/ToolShed/Data/Triple.hs
@@ -29,7 +29,11 @@
 -- ** Accessors
 	getFirst,
 	getSecond,
-	getThird
+	getThird,
+-- ** Mutators
+	mutateFirst,
+	mutateSecond,
+	mutateThird
 ) where
 
 -- | Extends the concept of 'Data.Tuple.curry'.
@@ -51,4 +55,16 @@
 -- | Access the third datum from the specified triple.
 getThird :: (a, b, c) -> c
 getThird (_, _, c)	= c
+
+-- | Operate on first datum.
+mutateFirst :: (a -> a') -> (a, b, c) -> (a', b, c)
+mutateFirst f (a, b, c)	= (f a, b, c)
+
+-- | Operate on second datum.
+mutateSecond :: (b -> b') -> (a, b, c) -> (a, b', c)
+mutateSecond f (a, b, c)	= (a, f b, c)
+
+-- | Operate on third datum.
+mutateThird :: (c -> c') -> (a, b, c) -> (a, b, c')
+mutateThird f (a, b, c)	= (a, b, f c)
 
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs b/src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs
--- a/src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs
+++ b/src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs
@@ -25,27 +25,35 @@
 	results
 ) where
 
+import			Control.Arrow((&&&))
 import qualified	Data.List
-import qualified	Data.Ord
+import qualified	Data.List.Extra
 import qualified	Data.Set
-import qualified	ToolShed.Data.Foldable
-import qualified	ToolShed.Data.List
 import qualified	Test.QuickCheck
+import qualified	ToolShed.Data.Foldable
+import			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
-	 )
+	let
+		f :: Int -> Test.QuickCheck.Property
+		f n	= Test.QuickCheck.label "prop_gatherSet" . (== l) . concat . ToolShed.Data.Foldable.gather $ Data.Set.fromDistinctAscList l	where
+			l	= [0 .. n `mod` 1024]
+	in Test.QuickCheck.quickCheckResult f,
+	let
+		f :: [Int] -> Test.QuickCheck.Property
+		f	= Test.QuickCheck.label "prop_gatherBy" . uncurry (==) . (
+			map Data.List.sort . ToolShed.Data.Foldable.gatherBy even &&& map Data.List.sort . Data.List.Extra.groupSortOn even
+		 )
+	in Test.QuickCheck.quickCheckResult f,
+	let
+		f :: [Int] -> Test.QuickCheck.Property
+		f l	= not (null l) ==> Test.QuickCheck.label "prop_hasDuplicates" . ToolShed.Data.Foldable.hasDuplicates $ l ++ l
+	in Test.QuickCheck.quickCheckResult f,
+	let
+		f :: [Int] -> Test.QuickCheck.Property
+		f	= Test.QuickCheck.label "prop_hasDuplicates/unique" . not . ToolShed.Data.Foldable.hasDuplicates . Data.List.nub
+	in Test.QuickCheck.quickCheckResult f
+ ]
 
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs b/src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs
--- a/src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs
+++ b/src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs
@@ -30,7 +30,11 @@
 
 -- | 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
+results	= mapM Test.QuickCheck.quickCheckResult [prop_accessors, prop_mutators]	where
+	prop_accessors, prop_mutators :: (Int, Char, Rational, Integer) -> 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
+
+	prop_mutators quadruple	= Test.QuickCheck.label "prop_mutators" $ (
+		ToolShed.Data.Quadruple.mutateForth pred . ToolShed.Data.Quadruple.mutateForth succ . ToolShed.Data.Quadruple.mutateThird pred . ToolShed.Data.Quadruple.mutateThird succ . ToolShed.Data.Quadruple.mutateSecond pred . ToolShed.Data.Quadruple.mutateSecond succ . ToolShed.Data.Quadruple.mutateFirst pred $ ToolShed.Data.Quadruple.mutateFirst succ quadruple
+	 ) == quadruple
diff --git a/src-test/ToolShed/Test/QuickCheck/Data/Triple.hs b/src-test/ToolShed/Test/QuickCheck/Data/Triple.hs
--- a/src-test/ToolShed/Test/QuickCheck/Data/Triple.hs
+++ b/src-test/ToolShed/Test/QuickCheck/Data/Triple.hs
@@ -30,8 +30,11 @@
 
 -- | 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
+results	= mapM Test.QuickCheck.quickCheckResult [prop_accessors, prop_mutators]	where
+	prop_accessors, prop_mutators :: (Int, Char, Rational) -> 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
 
+	prop_mutators triple	= Test.QuickCheck.label "prop_mutators" $ (
+		ToolShed.Data.Triple.mutateThird pred . ToolShed.Data.Triple.mutateThird succ . ToolShed.Data.Triple.mutateSecond pred . ToolShed.Data.Triple.mutateSecond succ . ToolShed.Data.Triple.mutateFirst pred $ ToolShed.Data.Triple.mutateFirst succ triple
+	 ) == triple
diff --git a/src-test/ToolShed/Test/QuickCheck/System/Random.hs b/src-test/ToolShed/Test/QuickCheck/System/Random.hs
--- a/src-test/ToolShed/Test/QuickCheck/System/Random.hs
+++ b/src-test/ToolShed/Test/QuickCheck/System/Random.hs
@@ -43,7 +43,7 @@
 
 -- | 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
+getStandardDeviation x	= sqrt . getMean $ fmap ((^ (2 :: Int)) . subtract (getMean x :: Rational) . toRational) x
 
 -- | The constant test-results for this data-type.
 results :: IO [Test.QuickCheck.Result]
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.17.0.2
+Version:	0.18.0.0
 Cabal-version:	>= 1.10
 Copyright:	(C) 2010-2015 Dr. Alistair Ward
 License:	GPL
@@ -41,7 +41,7 @@
     type:	git
     location:	https://github.com/functionalley/ToolShed
 
--- Enable using: 'cabal configure -f llvm'.
+-- Enable using: 'runhaskell Setup configure -f llvm --verbose'.
 flag llvm
     Description:	Whether the 'llvm' compiler-backend has been installed and is required for code-generation.
     Manual:		True
@@ -54,7 +54,6 @@
 
     Exposed-modules:
         ToolShed.Data.Foldable
-        ToolShed.Data.Array.IArray
         ToolShed.Data.List
         ToolShed.Data.List.Runlength
         ToolShed.Data.List.Splits
@@ -88,13 +87,17 @@
         QuickCheck >= 2.2,
         random
 
-    if impl(ghc >= 7.4.1)
-        GHC-prof-options:	-fprof-auto -fprof-cafs
-    else
-        GHC-prof-options:	-auto-all -caf-all
+    if impl(ghc >= 7.0)
+        if flag(llvm)
+            GHC-options:	-fllvm
 
-    if impl(ghc >= 7.0) && flag(llvm)
-        GHC-options:	-fllvm
+        if impl(ghc >= 7.4.1)
+            GHC-prof-options:	-fprof-auto -fprof-cafs
+    
+            if impl(ghc >= 8.0)
+                GHC-options:	-j -Wredundant-constraints
+        else
+            GHC-prof-options:	-auto-all -caf-all
 
 Test-Suite test
     Default-language:	Haskell2010
@@ -118,8 +121,12 @@
     Build-depends:
         base == 4.*,
         containers >= 0.4.2.0,
+        extra,
         HUnit,
         QuickCheck >= 2.2,
         random,
         toolshed
+
+    if impl(ghc >= 8.0)
+        GHC-options:	-j -Wredundant-constraints
 
