diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,6 +1,6 @@
 # **Factory**
 
-[![Build Status](https://travis-ci.org/functionalley/Factory.svg?branch=master)](https://travis-ci.org/functionalley/Factory)
+[![Build Status](https://travis-ci.com/functionalley/Factory.svg?branch=master)](https://travis-ci.com/functionalley/Factory)
 [![Hackage](https://img.shields.io/hackage/v/factory.svg)](https://hackage.haskell.org/package/factory)
 [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
 [![Haskell](https://b.repl.ca/v1/language-haskell-yellow.png)](https://haskell.org)
@@ -9,8 +9,11 @@
 
 ## Installation
 
-It can be built and installed using [Cabal](https://www.haskell.org/cabal/users-guide/installing-packages.html).
+It can be built and installed using:
 
+* [Cabal](https://www.haskell.org/cabal/),
+* [The Haskell Tool Stack](https://docs.haskellstack.org/en/stable/README/).
+
 ## Documentation
 
 More information about this library can be found at [Factory](https://functionalley.com/Factory/factory.html).
@@ -27,9 +30,9 @@
 
 The test-suite can be run using:
 
-    cabal configure --enable-tests;
-    cabal build;
-    cabal test --show-details=always;
+* "**cabal configure --enable-tests && cabal build && cabal test --show-details=always**",
+* "**stack test**",
+* "**make test**" issued from the product's installation-directory.
 
 ## Author
 
diff --git a/changelog.markdown b/changelog.markdown
--- a/changelog.markdown
+++ b/changelog.markdown
@@ -173,3 +173,6 @@
 
 ## 0.3.2.2
 Updated list of test-compilers.
+
+## 0.3.2.3
+Attempt to make tests more reliable.
diff --git a/factory.cabal b/factory.cabal
--- a/factory.cabal
+++ b/factory.cabal
@@ -1,3 +1,5 @@
+cabal-version: 2.4
+
 -- This file is part of Factory.
 --
 -- Factory is free software: you can redistribute it and/or modify
@@ -14,10 +16,9 @@
 -- along with Factory.  If not, see <http://www.gnu.org/licenses/>.
 
 Name:		factory
-Version:	0.3.2.2
-Cabal-version:	>= 1.10
+Version:	0.3.2.3
 Copyright:	(C) 2011-2015 Dr. Alistair Ward
-License:	GPL
+License:	GPL-3.0-or-later
 License-file:	LICENSE
 Author:		Dr. Alistair Ward
 Stability:	stable
@@ -25,7 +26,7 @@
 Build-type:	Simple
 Description:	A library of number-theory functions, for; factorials, square-roots, Pi and primes.
 Category:	Math, Number Theory
-Tested-with:	GHC == 7.4, GHC == 7.6, GHC == 7.8, GHC == 7.10, GHC == 8.0, GHC == 8.2, GHC == 8.4, GHC == 8.6, GHC == 8.8, GHC == 8.10
+Tested-with:	GHC == 8.0, GHC == 8.4, GHC == 8.8, GHC == 8.10
 Homepage:	https://functionalley.com/Factory/factory.html
 Maintainer:	mailto:factory@functionalley.com
 Bug-reports:	mailto:factory@functionalley.com
@@ -35,6 +36,7 @@
     .ghci
     changelog.markdown
     copyright
+    makefile
     README.markdown
 
 source-repository head
@@ -54,7 +56,8 @@
 
 Library
     Default-language:	Haskell2010
-    GHC-options:	-O2 -Wall -fno-warn-tabs
+    GHC-options:	-O2 -Wall -fno-warn-tabs -fno-warn-unused-top-binds -Wno-all-missed-specialisations
+
     Hs-source-dirs:	src-lib
 
     Exposed-modules:
@@ -144,11 +147,7 @@
     GHC-options:	-O2 -Wall -fno-warn-tabs
     Hs-source-dirs:	src-exe
     Main-is:		Main.hs
-
-    if impl(ghc >= 7.4.1)
-        GHC-prof-options:	-fprof-auto -fprof-cafs
-    else
-        GHC-prof-options:	-auto-all -caf-all
+    Autogen-modules:	Paths_factory
 
 -- Unexposed modules must be referenced for 'cabal sdist'.
     Other-modules:
diff --git a/makefile b/makefile
new file mode 100644
--- /dev/null
+++ b/makefile
@@ -0,0 +1,62 @@
+# This file is part of Factory.
+#
+# Factory 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.
+#
+# Factory 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 Factory.  If not, see <http://www.gnu.org/licenses/>.
+
+.PHONY: hlint test prof cabalCheck sdist findOmissions haddock graphmod
+
+PACKAGE_NAME	= factory
+SHELL		= /bin/bash
+GHC_OPTIONS	= --ghc-options='-j'
+BIN_DIR		= $$HOME/.local/bin/
+
+# Build hlint.
+$(BIN_DIR)/hlint:
+	@stack install hlint
+
+# Check for lint.
+hlint: $(BIN_DIR)/hlint
+	@$@ src-*
+
+# Compile & run the test-suite.
+test:
+	stack '$@' $(GHC_OPTIONS)
+
+# Profile.
+prof:
+	@stack install --library-profiling --executable-profiling $(GHC_OPTIONS)
+
+# Check the cabal-file.
+cabalCheck:
+	@cabal check
+
+# Package for upload to Hackage.
+sdist:
+	@cabal '$@'
+
+# Find source-files missing from the distribution.
+findOmissions: sdist
+	@diff <(find src-* -type f -name '*.hs' | sed 's!^\./!!' | sort) <(tar -ztf dist*/sdist/$(PACKAGE_NAME)-*.tar.gz | grep '\.hs$$' | grep -v 'Setup.hs' | sed 's!^$(PACKAGE_NAME)-[0-9.]*/!!' | sort)
+
+# Install this product.
+$(BIN_DIR)/$(PACKAGE_NAME):
+	@stack install $(GHC_OPTIONS)
+
+# Build the source-code documentation.
+haddock:
+	@stack '$@' --no-$@-deps $(GHC_OPTIONS)
+
+# Show module-dependency graph.
+graphmod:
+	@$@ --graph-dim='40,24' -i 'src-exe' -i 'src-lib' Main | tred | dot -Tsvg | display
+
diff --git a/src-exe/Main.hs b/src-exe/Main.hs
--- a/src-exe/Main.hs
+++ b/src-exe/Main.hs
@@ -27,7 +27,7 @@
 module Main(main) where
 
 import qualified	Data.Default
-import qualified	Data.Map
+import qualified	Data.Map.Strict
 import qualified	Data.List
 import qualified	Data.Version
 import qualified	Factory.Math.Hyperoperation			as Math.Hyperoperation
@@ -183,7 +183,7 @@
 				distribution :: Math.Probability.DiscreteDistribution Double
 				(n, distribution)	= readCommandArg arg
 			 in do
-				System.Random.getStdGen >>= print . Data.Map.toList . Data.Map.map ((/ (fromIntegral n :: Double)) . fromInteger) . Data.Map.fromListWith (+) . (`zip` repeat 1) . (take n :: [Integer] -> [Integer]) . Math.Probability.generateDiscretePopulation distribution
+				System.Random.getStdGen >>= print . Data.Map.Strict.toList . Data.Map.Strict.map ((/ (fromIntegral n :: Double)) . fromInteger) . Data.Map.Strict.fromListWith (+) . (`zip` repeat 1) . (take n :: [Integer] -> [Integer]) . Math.Probability.generateDiscretePopulation distribution
 
 				System.Exit.exitSuccess
 
diff --git a/src-lib/Factory/Math/Implementations/Primality.hs b/src-lib/Factory/Math/Implementations/Primality.hs
--- a/src-lib/Factory/Math/Implementations/Primality.hs
+++ b/src-lib/Factory/Math/Implementations/Primality.hs
@@ -110,10 +110,12 @@
 	Math.PrimeFactorisation.Algorithmic	factorisationAlgorithm,
 	Show					i
  ) => factorisationAlgorithm -> i -> Bool
-isPrimeByAKS factorisationAlgorithm n	= and [
-	not $ Math.PerfectPower.isPerfectPower n,	-- Step 1.
-	Math.Primality.areCoprime n `all` Data.List.delete n [2 .. r],	-- Step 3.
-	and $ Control.Parallel.Strategies.parMap Control.Parallel.Strategies.rdeepseq	{-Benefits from '+RTS -H100M', which reduces garbage-collections-} (
+isPrimeByAKS factorisationAlgorithm n	= not (
+	Math.PerfectPower.isPerfectPower n	-- Step 1.
+ ) && (
+	Math.Primality.areCoprime n `all` Data.List.delete n [2 .. r]	-- Step 3.
+ ) && and (
+	Control.Parallel.Strategies.parMap Control.Parallel.Strategies.rdeepseq	{-Benefits from '+RTS -H100M', which reduces garbage-collections-} (
 		\a	-> let
 --			lhs, rhs :: Data.Polynomial.Polynomial i i
 			lhs	= Data.Polynomial.raiseModulo (Data.Polynomial.mkLinear 1 a) n {-power-} n {-modulus-}
@@ -128,7 +130,7 @@
 	) [
 		1 .. floor . (* lg) . sqrt $ fromIntegral r
 	] -- Step 4; (x + a)^n ~ x^n + a mod (x^r - 1, n).
- ] where
+ ) where
 	lg :: Double
 	lg	= logBase 2 $ fromIntegral n
 
diff --git a/src-lib/Factory/Math/Implementations/PrimeFactorisation.hs b/src-lib/Factory/Math/Implementations/PrimeFactorisation.hs
--- a/src-lib/Factory/Math/Implementations/PrimeFactorisation.hs
+++ b/src-lib/Factory/Math/Implementations/PrimeFactorisation.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE LambdaCase #-}
 {-
 	Copyright (C) 2011-2017 Dr. Alistair Ward
 
@@ -64,7 +65,7 @@
 	def	= TrialDivision
 
 instance Math.PrimeFactorisation.Algorithmic Algorithm	where
-	primeFactors algorithm	= case algorithm of
+	primeFactors = \case
 		DixonsMethod	-> factoriseByDixonsMethod
 		FermatsMethod	-> Data.PrimeFactors.reduce . factoriseByFermatsMethod
 		TrialDivision	-> factoriseByTrialDivision
diff --git a/src-lib/Factory/Math/PrimeFactorisation.hs b/src-lib/Factory/Math/PrimeFactorisation.hs
--- a/src-lib/Factory/Math/PrimeFactorisation.hs
+++ b/src-lib/Factory/Math/PrimeFactorisation.hs
@@ -146,5 +146,9 @@
 	* <https://en.wikipedia.org/wiki/Square-free_integer>.
 -}
 squareFree :: (Algorithmic algorithm, Control.DeepSeq.NFData i, Integral i) => algorithm -> [i]
-squareFree algorithm	= filter (all (== 1) . map Data.Exponential.getExponent . primeFactors algorithm) [1 ..]
+squareFree algorithm	= filter (
+	all (
+		(== 1) . Data.Exponential.getExponent
+	) . primeFactors algorithm
+ ) [1 ..]
 
diff --git a/src-test/Factory/Test/QuickCheck/Factorial.hs b/src-test/Factory/Test/QuickCheck/Factorial.hs
--- a/src-test/Factory/Test/QuickCheck/Factorial.hs
+++ b/src-test/Factory/Test/QuickCheck/Factorial.hs
@@ -60,9 +60,9 @@
 
 	prop_symmetry x n	= Test.QuickCheck.label "prop_symmetry" $ Math.Implementations.Factorial.risingFactorial x n == Math.Implementations.Factorial.fallingFactorial (pred $ x + n) n
 
-	prop_x0 x _		= Test.QuickCheck.label "prop_x0" $ all (== 1) $ map ($ 0) [Math.Implementations.Factorial.risingFactorial x, Math.Implementations.Factorial.fallingFactorial x]
+	prop_x0 x _		= Test.QuickCheck.label "prop_x0" $ all ((== 1) . ($ 0)) [Math.Implementations.Factorial.risingFactorial x, Math.Implementations.Factorial.fallingFactorial x]
 
-	prop_0n _ n		= Test.QuickCheck.label "prop_0n" $ all (== if n == 0 then 1 else 0) $ map ($ n) [Math.Implementations.Factorial.risingFactorial 0, Math.Implementations.Factorial.fallingFactorial 0]
+	prop_0n _ n		= Test.QuickCheck.label "prop_0n" $ all ((== if n == 0 then 1 else 0) . ($ n)) [Math.Implementations.Factorial.risingFactorial 0, Math.Implementations.Factorial.fallingFactorial 0]
 
 	prop_ratio :: Math.Implementations.Factorial.Algorithm -> Integer -> Integer -> Test.QuickCheck.Property
 	prop_ratio algorithm i j	= Test.QuickCheck.label "prop_ratio" $ n !/! d == Math.Factorial.factorial algorithm n % Math.Factorial.factorial algorithm d	where
diff --git a/src-test/Factory/Test/QuickCheck/Pi.hs b/src-test/Factory/Test/QuickCheck/Pi.hs
--- a/src-test/Factory/Test/QuickCheck/Pi.hs
+++ b/src-test/Factory/Test/QuickCheck/Pi.hs
@@ -101,8 +101,10 @@
 
 -- | The constant test-results for this data-type.
 results :: IO [Test.QuickCheck.Result]
-results	= mapM Test.QuickCheck.quickCheckResult [prop_consistency]	where
+results	= mapM (
+	Test.QuickCheck.quickCheckWithResult Test.QuickCheck.stdArgs { Test.QuickCheck.maxSuccess = 256 }
+ ) [prop_consistency]	where
 	prop_consistency :: Testable
-	prop_consistency l r decimalDigits	= l /= r	==> Test.QuickCheck.label "prop_consistency" $ Math.Pi.openI l decimalDigits' - Math.Pi.openI r decimalDigits' <= 1 {-rounding error-}	where
+	prop_consistency l r decimalDigits	= l /= r	==> Test.QuickCheck.label "prop_consistency" $ Math.Pi.openI l decimalDigits' - Math.Pi.openI r decimalDigits' <= 2 {-rounding error-}	where
 		decimalDigits'	= succ $ decimalDigits `mod` 250
 
diff --git a/src-test/Factory/Test/QuickCheck/Probability.hs b/src-test/Factory/Test/QuickCheck/Probability.hs
--- a/src-test/Factory/Test/QuickCheck/Probability.hs
+++ b/src-test/Factory/Test/QuickCheck/Probability.hs
@@ -60,7 +60,7 @@
 		Math.Statistics.getMean &&& pred . Math.Statistics.getStandardDeviation	-- Both of which, having been normalised, should be zero.
 	 ) . (
 		normalise distribution :: [Double] -> [Double]
-	 ) . take 10000 $ Math.Probability.generatePopulation distribution randomGen	where
+	 ) . take 100000 $ Math.Probability.generatePopulation distribution randomGen	where
 		maxParameter	= log . fromInteger $ Math.Probability.maxPreciseInteger (undefined :: Double)
 		location'
 			| location >= 0	= maxParameter `min` location
@@ -134,7 +134,7 @@
 		Math.Statistics.getMean &&& pred . Math.Statistics.getStandardDeviation	-- Both of which, having been normalised, should be zero.
 	 ) . (
 		normalise distribution :: [Double] -> [Double]
-	 ) . take 10000 $ Math.Probability.generatePopulation distribution randomGen	where
+	 ) . take 100000 $ Math.Probability.generatePopulation distribution randomGen	where
 		probability'	= recip . succ $ abs probability	-- Semi-closed unit-interval (0, 1].
 		distribution	= Math.Probability.ShiftedGeometricDistribution probability'
 
diff --git a/src-test/Factory/Test/QuickCheck/SquareRoot.hs b/src-test/Factory/Test/QuickCheck/SquareRoot.hs
--- a/src-test/Factory/Test/QuickCheck/SquareRoot.hs
+++ b/src-test/Factory/Test/QuickCheck/SquareRoot.hs
@@ -47,20 +47,20 @@
 
 -- | The constant test-results for this data-type.
 results :: IO [Test.QuickCheck.Result]
-results	= mapM Test.QuickCheck.quickCheckResult [
---	prop_accuracy,	-- This occasionally fails.
-	prop_factorable
---	prop_perfectSquare	-- This occasionally fails.
+results	= sequence [
+--	Test.QuickCheck.quickCheckWithResult Test.QuickCheck.stdArgs { Test.QuickCheck.maxSuccess = 256 } prop_accuracy,	-- This occasionally fails.
+	Test.QuickCheck.quickCheckWithResult Test.QuickCheck.stdArgs { Test.QuickCheck.maxSuccess = 256 } prop_factorable
+--	Test.QuickCheck.quickCheckWithResult Test.QuickCheck.stdArgs { Test.QuickCheck.maxSuccess = 256 } prop_perfectSquare	-- This occasionally fails.
  ] where
 	prop_accuracy, prop_factorable, prop_perfectSquare :: (Math.Implementations.SquareRoot.Algorithm, Math.Precision.DecimalDigits, Rational) -> Test.QuickCheck.Property
 	prop_accuracy (algorithm, decimalDigits, operand)	= Test.QuickCheck.label "prop_accuracy" . (>= requiredDecimalDigits) . Math.SquareRoot.getAccuracy operand' $ Math.SquareRoot.squareRoot algorithm requiredDecimalDigits operand'	where
 		requiredDecimalDigits :: Math.Precision.DecimalDigits
-		requiredDecimalDigits	= succ $ decimalDigits `mod` 1024
+		requiredDecimalDigits	= succ $ decimalDigits `mod` 512
 
 		operand' :: Rational
 		operand'	= abs operand
 
-	prop_factorable (algorithm, decimalDigits, operand)	= Test.QuickCheck.label "prop_factorable" . (<= 5) . (
+	prop_factorable (algorithm, decimalDigits, operand)	= Test.QuickCheck.label "prop_factorable" . (<= 9) . (
 		* 10 ^ requiredDecimalDigits	-- Promote the relative error.
 	 ) . abs $ 1 - (
 		Math.SquareRoot.squareRoot algorithm requiredDecimalDigits (
diff --git a/src-test/Factory/Test/QuickCheck/Statistics.hs b/src-test/Factory/Test/QuickCheck/Statistics.hs
--- a/src-test/Factory/Test/QuickCheck/Statistics.hs
+++ b/src-test/Factory/Test/QuickCheck/Statistics.hs
@@ -27,7 +27,7 @@
 
 import qualified	Data.Array.IArray
 import qualified	Data.List
-import qualified	Data.Map
+import qualified	Data.Map.Strict
 import qualified	Data.Numbers.Primes
 import qualified	Data.Set
 import qualified	Factory.Math.Implementations.Factorial	as Math.Implementations.Factorial
@@ -99,7 +99,7 @@
 	prop_varianceOfArray l		= not (null l)	==> Test.QuickCheck.label "prop_varianceOfArray" $ Math.Statistics.getVariance (
 		Data.Array.IArray.array (1, length l) $ zip [1 ..] l :: Data.Array.IArray.Array Int Integer
 	 ) == (Math.Statistics.getVariance l :: Rational)
-	prop_varianceOfMap l		= not (null l)	==> Test.QuickCheck.label "prop_varianceOfMap" $ Math.Statistics.getVariance (Data.Map.fromList $ zip [0 :: Int ..] l) == (Math.Statistics.getVariance l :: Rational)
+	prop_varianceOfMap l		= not (null l)	==> Test.QuickCheck.label "prop_varianceOfMap" $ Math.Statistics.getVariance (Data.Map.Strict.fromList $ zip [0 :: Int ..] l) == (Math.Statistics.getVariance l :: Rational)
 	prop_meanOfSet l		= not (null l')	==> Test.QuickCheck.label "prop_meanOfSet" $ Math.Statistics.getMean (Data.Set.fromList l') == (Math.Statistics.getMean l' :: Rational)	where
 		l'	= Data.List.nub l
 
