packages feed

toolshed 0.16.0.0 → 0.17.0.2

raw patch · 37 files changed

+954/−621 lines, 37 filesdep +HUnitdep +data-default

Dependencies added: HUnit, data-default

Files

+ .ghci view
@@ -0,0 +1,1 @@+:set -isrc-lib:src-test:dist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h
README.markdown view
@@ -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 
changelog.markdown view
@@ -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.
@@ -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.
+ src-lib/ToolShed/Data/Array/IArray.hs view
@@ -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.+ ]
src-lib/ToolShed/Data/Foldable.hs view
@@ -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 
src-lib/ToolShed/Data/List.hs view
@@ -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. 
+ src-lib/ToolShed/Data/String.hs view
@@ -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+
− src-lib/ToolShed/Defaultable.hs
@@ -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)
src-lib/ToolShed/Options.hs view
@@ -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.
src-lib/ToolShed/SelfValidate.hs view
@@ -23,7 +23,7 @@ module ToolShed.SelfValidate( -- * Type-classes 	SelfValidator(..),--- ** Functions+-- * Functions 	getFirstError, 	extractErrors ) where
src-lib/ToolShed/System/File.hs view
@@ -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 "." 
src-lib/ToolShed/System/Random.hs view
@@ -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.
+ src-lib/ToolShed/Test/Ix.hs view
@@ -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+
src-lib/ToolShed/Test/QuickCheck/Arbitrary/Array.hs view
@@ -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) 
src-lib/ToolShed/Test/QuickCheck/Arbitrary/Map.hs view
@@ -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 
src-lib/ToolShed/Test/QuickCheck/Arbitrary/Set.hs view
@@ -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 
src-lib/ToolShed/Test/ReversibleIO.hs view
@@ -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+
src-test/Main.hs view
@@ -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  ] 
− src-test/ToolShed/Test/Data/Foldable.hs
@@ -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-	 )-
− src-test/ToolShed/Test/Data/List.hs
@@ -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']-
− src-test/ToolShed/Test/Data/List/Runlength.hs
@@ -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-
− src-test/ToolShed/Test/Data/List/Splits.hs
@@ -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
− src-test/ToolShed/Test/Data/Quadruple.hs
@@ -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
− src-test/ToolShed/Test/Data/Triple.hs
@@ -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-
+ src-test/ToolShed/Test/HUnit/Data/List.hs view
@@ -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 ?!+ ]
+ src-test/ToolShed/Test/QuickCheck/Data/Foldable.hs view
@@ -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+	 )+
+ src-test/ToolShed/Test/QuickCheck/Data/List.hs view
@@ -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)]+
+ src-test/ToolShed/Test/QuickCheck/Data/List/Runlength.hs view
@@ -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+
+ src-test/ToolShed/Test/QuickCheck/Data/List/Splits.hs view
@@ -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
+ src-test/ToolShed/Test/QuickCheck/Data/Quadruple.hs view
@@ -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
+ src-test/ToolShed/Test/QuickCheck/Data/Triple.hs view
@@ -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+
+ src-test/ToolShed/Test/QuickCheck/SelfValidate.hs view
@@ -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+
+ src-test/ToolShed/Test/QuickCheck/System/Random.hs view
@@ -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+
− src-test/ToolShed/Test/SelfValidate.hs
@@ -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-
− src-test/ToolShed/Test/System/Random.hs
@@ -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-
toolshed.cabal view
@@ -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-