packages feed

regexdot 0.11.1.0 → 0.11.1.1

raw patch · 17 files changed

+263/−323 lines, 17 filesdep ~parallelsetup-changedPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: parallel

API changes (from Hackage documentation)

Files

Setup.hs view
@@ -1,5 +1,5 @@ #!/usr/bin/env runhaskell -import qualified	Distribution.Simple+import qualified Distribution.Simple -main	= Distribution.Simple.defaultMain+main = Distribution.Simple.defaultMain
changelog view
@@ -40,3 +40,8 @@ 	* Removed 'Show' from the context of functions in "RegExDot.RegEx" 	* Exported a new constant 'RegExDot.Anchor.unanchored'. 	* Refactored 'RegExDot.ConsumptionProfile.withinConsumptionBounds'.+0.11.1.1+	* Tested with 'haskell-platform-2013.2.0.0'.+	* Replaced preprocessor-directives with 'build-depends' constraints in 'regexdot.cabal'.+	* In function 'RegExDot.RegEx.findMatch.findMatchSlave.matchPairList', changed 'fromIntegral' (which required a type-signature) to 'toRational'.+	* Either replaced instances of '(<$>)' with 'fmap' to avoid ambiguity between "Control.Applicative" & "Prelude" which (from 'base-4.8') also exports this symbol, or hid the symbol when importing the "Prelude"..
makefile view
@@ -1,4 +1,4 @@-# Copyright (C) 2010 Dr. Alistair Ward+# Copyright (C) 2010-2014 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@@ -40,10 +40,10 @@ 	PATH=~/.cabal/bin:$$PATH runhaskell Setup $@ --hyperlink-source	#Amend path to find 'HsColour', as required for 'hyperlink-source'.  hlint:-	@$@ -i 'Use &&' src/ -i 'Use ||'+	@$@ -i 'Use &&' src/ -i 'Use ||' +RTS -N  sdist:-	runhaskell Setup $@+	TAR_OPTIONS='--format=ustar' runhaskell Setup $@  check: sdist 	cabal upload --check --verbose=3 dist/*.tar.gz;
regexdot.cabal view
@@ -1,8 +1,8 @@---Package-properties+-- Package-properties Name:			regexdot-Version:		0.11.1.0+Version:		0.11.1.1 Cabal-Version:		>= 1.6-Copyright:		(C) 2010 Dr. Alistair Ward+Copyright:		(C) 2010-2015 Dr. Alistair Ward License:		GPL License-file:		LICENSE Author:			Dr. Alistair Ward@@ -11,25 +11,18 @@ Build-Type:		Simple Description:		Provides a portable, POSIX, extended regex-engine, designed to process a list of /arbitrary/ objects. Category:		Search, Regex-Tested-With:		GHC == 6.10, GHC == 6.12, GHC == 7.0, GHC == 7.4+Tested-With:		GHC == 6.10, GHC == 6.12, GHC == 7.0, GHC == 7.4, GHC == 7.6, GHC == 7.10 Homepage:		http://functionalley.eu Maintainer:		regexdot <at> functionalley <dot> eu Bug-reports:		regexdot <at> functionalley <dot> eu Extra-Source-Files:	changelog, copyright, makefile -flag haveDeepSeq-    Description:	Import the type-class 'NFData' from module 'Control.DeepSeq' rather than 'Control.Parallel.Strategies'.-    Default:		True-+-- Turn on using: 'runhaskell ./Setup.hs configure -f llvm'. flag llvm     Description:	Whether the 'llvm' compiler-backend has been installed and is required for code-generation.     manual:		True     default:		False -flag threaded-    Description:	Enable parallelized code.-    default:		True- Library     hs-source-dirs:	src @@ -57,29 +50,17 @@      Build-depends:         base == 4.*,+        deepseq >= 1.1,+        parallel >= 3.0,         parsec == 3.*,         toolshed >= 0.13 -    GHC-options:	-Wall -O2+    GHC-options:	-Wall -O2 -fno-warn-tabs      if impl(ghc >= 7.4.1)         GHC-prof-options:	-prof -fprof-auto -fprof-cafs     else         GHC-prof-options:	-prof -auto-all -caf-all--    if flag(haveDeepSeq)-        Build-depends:	deepseq >= 1.1-        CPP-options:	-DHAVE_DEEPSEQ-    else-        Build-depends:	parallel == 1.*--    if flag(threaded)-        Build-depends:	parallel >= 3.0--        if impl(ghc >= 6.12)-            GHC-options:	-feager-blackholing-    else-        Build-depends:	parallel      if impl(ghc >= 7.0) && flag(llvm)         GHC-options:	-fllvm
src/RegExDot/Anchor.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {- 	Copyright (C) 2010 Dr. Alistair Ward @@ -43,11 +42,7 @@ 	unanchored ) where -#ifdef HAVE_DEEPSEQ-import	Control.DeepSeq(NFData, rnf)-#else-import	Control.Parallel.Strategies(NFData, rnf)-#endif+import qualified	Control.DeepSeq  -- | Defines the types on /anchor/ by which a /regex/ can be moored to a part of the input-data. data Anchor =@@ -55,8 +50,8 @@ 	| Stern	-- ^ Matches only if no input data remains to be consumed. Can only exist at the end of the entire regex, or (in theory) the end of any /alternative/. 	deriving ( 		Eq---		Read,	--See specialisation below.---		Show	--See specialisation below.+--		Read,	-- See specialisation below.+--		Show	-- See specialisation below. 	)  instance Show Anchor	where@@ -64,14 +59,14 @@ 	showsPrec _ Stern	= showChar sternToken  instance Read Anchor	where-	readsPrec _ []		= []	--No parse.-	readsPrec _ (' ' : s)	= reads s	--Consume white-space.-	readsPrec _ ('\t' : s)	= reads s	--Consume white-space.+	readsPrec _ []		= []	-- No parse.+	readsPrec _ (' ' : s)	= reads s	-- Consume white-space.+	readsPrec _ ('\t' : s)	= reads s	-- Consume white-space. 	readsPrec _ (c : s)	= case c `lookup` [(bowToken, Bow), (sternToken, Stern)] of 		Just anchor	-> [(anchor, s)]-		_		-> []	--No parse.+		_		-> []	-- No parse. -instance NFData Anchor	where+instance Control.DeepSeq.NFData Anchor	where 	rnf _	= ()  -- | The conventional token used to denote a 'Bow'-anchor, when in 'String'-form.
src/RegExDot/BracketExpressionMember.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {- 	Copyright (C) 2010 Dr. Alistair Ward @@ -41,15 +40,10 @@ ) where  import qualified	Control.Arrow+import qualified	Control.DeepSeq import qualified	RegExDot.ShowablePredicate	as ShowablePredicate -#ifdef HAVE_DEEPSEQ-import			Control.DeepSeq(NFData, rnf)-#else-import			Control.Parallel.Strategies(NFData, rnf)-#endif--infix 4 =~	--Same as (==).+infix 4 =~	-- Same as (==).  {- | 	* The interface via which /Perl-style shortcut/s are expanded (when they occur within a /bracket-expression/), in a manner appropriate to the chosen type-parameter.@@ -77,17 +71,17 @@ 	showsPrec _ (Literal literal)			= shows literal  instance (ShortcutExpander m, Read m) => Read (Member m)	where-	readsPrec _ []				= []		--No parse.-	readsPrec _ (' ' : s)			= reads s	--Consume white-space.-	readsPrec _ ('\t' : s)			= reads s	--Consume white-space.+	readsPrec _ []				= []		-- No parse.+	readsPrec _ (' ' : s)			= reads s	-- Consume white-space.+	readsPrec _ ('\t' : s)			= reads s	-- Consume white-space. 	readsPrec _ ('\\' : shortcut : s)	= case findPredicate shortcut of 		Just showablePredicate	-> [(Predicate showablePredicate, s)] 		_			-> error $ "readsPrec RegExDot.BracketExpressionMember.Member:\tfindPredicate failed for shortcut " ++ show shortcut 	readsPrec _ literal			= Control.Arrow.first Literal `map` reads literal -instance NFData m => NFData (Member m)	where-	rnf (Predicate showablePredicate)	= rnf showablePredicate-	rnf (Literal literal)			= rnf literal+instance Control.DeepSeq.NFData m => Control.DeepSeq.NFData (Member m)	where+	rnf (Predicate showablePredicate)	= Control.DeepSeq.rnf showablePredicate+	rnf (Literal literal)			= Control.DeepSeq.rnf literal  -- | Match-operator. (=~) :: Eq m
src/RegExDot/Consumer.hs view
@@ -101,5 +101,5 @@  -- | Get the 'ConsumptionProfile.ConsumptionProfile' for the specified list of 'Consumer's, then accumulate them. accumulateConsumptionProfiles :: Consumer c => [c] -> ConsumptionProfile.AccumulatedConsumptionProfiles-accumulateConsumptionProfiles	= {-init .-} accumulateConsumptionProfilesFrom ConsumptionProfile.zero	--It's useful to leave the initial value at the end of the list.+accumulateConsumptionProfiles	= {-init .-} accumulateConsumptionProfilesFrom ConsumptionProfile.zero	-- It's useful to leave the initial value at the end of the list. 
src/RegExDot/ConsumptionProfile.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@@ -42,6 +42,7 @@ 	withinConsumptionBounds ) where +import Prelude hiding ((<$>), (<*>))	-- The "Prelude" from 'base-4.8' exports this symbol. import			Control.Applicative((<$>), (<*>)) import			Control.Arrow((***)) import qualified	Data.List@@ -49,8 +50,8 @@ import qualified	RegExDot.ConsumptionBounds	as ConsumptionBounds import qualified	ToolShed.SelfValidate -infixr 5 |+|	--Same as (++).-infixr 2 <>	--Same as (||).+infixr 5 |+|	-- Same as (++).+infixr 2 <>	-- Same as (||).  {- | 	* A 'Consumer' is considered to have a 'ConsumptionProfile' composed from both a capacity to consume, & an ability to discriminate.@@ -113,9 +114,9 @@ 	hasSpecificRequirement	= rh, 	canConsumeAnything	= rc } = MkConsumptionProfile {-	consumptionBounds	= (lf + rf, (+) <$> ls <*> rs),	--The sum of those of the concatenation.-	hasSpecificRequirement	= lh || rh,			--The concatenation mandates consumption of at least one specific input datum, if either 'ConsumptionProfile' does.-	canConsumeAnything	= lc || rc			--The concatenation can consume at least one arbitrary input datum, if either 'ConsumptionProfile' can.+	consumptionBounds	= (lf + rf, (+) <$> ls <*> rs),	-- The sum of those of the concatenation.+	hasSpecificRequirement	= lh || rh,			-- The concatenation mandates consumption of at least one specific input datum, if either 'ConsumptionProfile' does.+	canConsumeAnything	= lc || rc			-- The concatenation can consume at least one arbitrary input datum, if either 'ConsumptionProfile' can. }  -- | The net effect of two alternative 'ConsumptionProfile's.@@ -129,9 +130,9 @@ 	hasSpecificRequirement	= rh, 	canConsumeAnything	= rc } = MkConsumptionProfile {-	consumptionBounds	= (lf `min` rf, max <$> ls <*> rs),	--Stretched to envelope alternatives.-	hasSpecificRequirement	= lh && rh,				--The alternation mandates consumption of at least one specific input datum, if both 'ConsumptionProfile's do.-	canConsumeAnything	= lc || rc				--The alternation can consume at least one arbitrary input datum, if either 'ConsumptionProfile' can.+	consumptionBounds	= (lf `min` rf, max <$> ls <*> rs),	-- Stretched to envelope alternatives.+	hasSpecificRequirement	= lh && rh,				-- The alternation mandates consumption of at least one specific input datum, if both 'ConsumptionProfile's do.+	canConsumeAnything	= lc || rc				-- The alternation can consume at least one arbitrary input datum, if either 'ConsumptionProfile' can. }  -- | The aggregate of the specified concatenation of 'ConsumptionProfile's.
src/RegExDot/DSL.hs view
@@ -51,7 +51,7 @@ import qualified	RegExDot.RegEx		as RegEx import qualified	RegExDot.Repeatable	as Repeatable -infixr 5 -:, ?:, ??:, *:, *?:, +:, +?:,#->#:, #->#?:, #->:, #->?:, #:, <~>	--Same as for ':', & lower than Repeatable's operators.+infixr 5 -:, ?:, ??:, *:, *?:, +:, +?:,#->#:, #->#?:, #->:, #->?:, #:, <~>	-- Same as for ':', & lower than Repeatable's operators.  -- | Prepend an unrepeated 'RegEx.Pattern', to the specified 'RegEx.Concatenation'. (-:) :: RegEx.Pattern a -> RegEx.Concatenation a -> RegEx.Concatenation a
src/RegExDot/DataSpanTree.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,6 @@ 	toTreeList ) where -import			Control.Applicative((<$>)) import qualified	Data.Foldable import qualified	RegExDot.ConsumptionBounds	as ConsumptionBounds import qualified	RegExDot.DataSpan		as DataSpan@@ -48,7 +47,7 @@ toTreeList :: RegEx.MatchList a -> DataSpanTreeList a toTreeList	= map toTree	where 	toTree :: RegEx.Match a -> DataSpanTree a-	toTree	= (toDataSpan <$>)	where+	toTree	= fmap toDataSpan	where 		toDataSpan :: RegEx.MatchedData a -> DataSpan.DataSpan a 		toDataSpan (_, inputDataOffset, inputData)	= (inputData, (inputDataOffset, length inputData)) @@ -99,7 +98,7 @@ 		recurseHorizontallyFrom	= (`extractCaptureGroups'` treeList) 	 in case tree of 		Tree.Leaf dataSpan	-> recurseHorizontallyFrom $ DataSpan.after dataSpan-		Tree.Node []		-> DataSpan.empty (if complyStrictlyWithPosix then -1 else offset) : recurseHorizontallyFrom offset	--POSIX specifies an Span-offset of -1, for sub-expressions which match 0 times; cf sub-expressions which consumes nothing, once.+		Tree.Node []		-> DataSpan.empty (if complyStrictlyWithPosix then -1 else offset) : recurseHorizontallyFrom offset	-- POSIX specifies an Span-offset of -1, for sub-expressions which match 0 times; cf sub-expressions which consumes nothing, once. 		Tree.Node treeLists	-> joinedFlattenedTreeList : (extractCaptureGroups' offset lastMatch {-recurse vertically-} ++ recurseHorizontallyFrom (DataSpan.after joinedFlattenedTreeList))	where --			lastMatch :: DataSpanTreeList a 			lastMatch	= last treeLists	-- <http://www.opengroup.org/onlinepubs/009695399/functions/regcomp.html>.
src/RegExDot/ExecutionOptions.hs view
@@ -59,17 +59,17 @@  instance ToolShed.Defaultable.Defaultable ExecutionOptions	where 	defaultValue	= setVerbose False $ ToolShed.Options.blankValue {-		abortTrialRepetitionsOnInherentFailure	= True,		--Regrettably, this slightly reduces performance for most non-pathological patterns.+		abortTrialRepetitionsOnInherentFailure	= True,		-- Regrettably, this slightly reduces performance for most non-pathological patterns. 		catchIncompatibleAnchors		= True, 		checkExistenceOfInelasticTail		= True,-		checkForUnconsumableData		= True,		--Expensive, particularly when (not requireMatchList), & only typically useful in failure-scenarios.-		moderateGreed				= True,		--Cost may exceed benefit. TODO: confirm.+		checkForUnconsumableData		= True,		-- Expensive, particularly when (not requireMatchList), & only typically useful in failure-scenarios.+		moderateGreed				= True,		-- Cost may exceed benefit. TODO: confirm. 		preferAlternativesWhichFeedTheGreedy	= True, 		preferAlternativesWhichMimickUnrolling	= True, 		preferFewerRepeatedAlternatives		= True,-		unrollRepeatedSingletonAlternative	= True,		--Affects only efficiency, not the result.-		useFirstMatchAmongAlternatives		= False,	--Perl-style matching may be faster, but may also yield a sub-optimal Match.-		validateMinConsumptionOfAlternatives	= False		--The cost outweighs the small infrequent dividend.+		unrollRepeatedSingletonAlternative	= True,		-- Affects only efficiency, not the result.+		useFirstMatchAmongAlternatives		= False,	-- Perl-style matching may be faster, but may also yield a sub-optimal Match.+		validateMinConsumptionOfAlternatives	= False		-- The cost outweighs the small infrequent dividend. 	}  instance ToolShed.Options.Options ExecutionOptions	where@@ -94,9 +94,9 @@ -- | Sets those fields which depend crucially on whether the caller wants to retrieve any /RegExDot.RegEx.MatchList/ from the /RegExDot.RegEx.Result/, or just query whether there is one. setVerbose :: Bool -> ExecutionOptions -> ExecutionOptions setVerbose verbose e	= e {-	abortTrialRepetitionsOnZeroConsumption	= verbose,	--The corresponding check, involves evaluation of a /RegExDot.RegEx.MatchList/, which is too expensive if the /RegExDot.RegEx.Matchlist/ isn't otherwise required.-	bypassInputDataForLiberalConsumer	= not verbose,	--Potentially bypasses reading of /RegExDot.RegEx.InputData/, which is inappropriate if the mapping into a /RegExDot.RegEx.Result/ is required.-	permitReorderingOfAlternatives		= not verbose,	--Doesn't help when 'requireMatchList', since an exhaustive search of /RegExDot.RegEx.Alternatives/, for the optimal solution, is performed.+	abortTrialRepetitionsOnZeroConsumption	= verbose,	-- The corresponding check, involves evaluation of a /RegExDot.RegEx.MatchList/, which is too expensive if the /RegExDot.RegEx.Matchlist/ isn't otherwise required.+	bypassInputDataForLiberalConsumer	= not verbose,	-- Potentially bypasses reading of /RegExDot.RegEx.InputData/, which is inappropriate if the mapping into a /RegExDot.RegEx.Result/ is required.+	permitReorderingOfAlternatives		= not verbose,	-- Doesn't help when 'requireMatchList', since an exhaustive search of /RegExDot.RegEx.Alternatives/, for the optimal solution, is performed. 	requireMatchList			= verbose } 
src/RegExDot/Meta.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {- 	Copyright (C) 2010 Dr. Alistair Ward @@ -48,6 +47,7 @@ ) where  import qualified	Control.Arrow+import qualified	Control.DeepSeq import qualified	RegExDot.BracketExpression		as BracketExpression import qualified	RegExDot.BracketExpressionMember	as BracketExpressionMember import qualified	RegExDot.Consumer			as Consumer@@ -55,12 +55,6 @@ import qualified	RegExDot.ShowablePredicate		as ShowablePredicate import qualified	ToolShed.SelfValidate -#ifdef HAVE_DEEPSEQ-import			Control.DeepSeq(NFData, rnf)-#else-import			Control.Parallel.Strategies(NFData, rnf)-#endif- {- | 	* The interface via which /Perl-style shortcut/s are expanded, in a manner appropriate to the chosen type-parameter. @@ -79,8 +73,8 @@ 	| Predicate (ShowablePredicate.ShowablePredicate m)	-- ^ The datum matches if 'ShowablePredicate.ShowablePredicate'. 	deriving ( 		Eq---		Read,	--Specialised below.---		Show	--Specialised below.+--		Read,	-- Specialised below.+--		Show	-- Specialised below. 	)  instance ToolShed.SelfValidate.SelfValidator (Meta m)	where@@ -94,9 +88,9 @@ 	showsPrec _ (Predicate showablePredicate)	= shows showablePredicate  instance (ShortcutExpander m, Read m) => Read (Meta m)	where-	readsPrec _ []				= []		--No parse.-	readsPrec _ (' ' : s)			= reads s	--Consume white-space.-	readsPrec _ ('\t' : s)			= reads s	--Consume white-space.+	readsPrec _ []				= []		-- No parse.+	readsPrec _ (' ' : s)			= reads s	-- Consume white-space.+	readsPrec _ ('\t' : s)			= reads s	-- Consume white-space. 	readsPrec _ ('.' : s)			= [(Any, s)] 	readsPrec _ ('[' : '^' : noneOf)	= Control.Arrow.first NoneOf `map` reads (fst BracketExpression.delimiterTokens : noneOf) {-Reconstruct without negation, & recurse-} 	readsPrec _ anyOf@('[' : _)		= Control.Arrow.first AnyOf `map` reads anyOf {-singleton-}@@ -118,12 +112,12 @@  	starHeight _	= 0 -instance NFData m => NFData (Meta m)	where+instance Control.DeepSeq.NFData m => Control.DeepSeq.NFData (Meta m)	where 	rnf Any					= ()-	rnf (Literal m)				= rnf m-	rnf (AnyOf bracketExpression)		= rnf bracketExpression-	rnf (NoneOf bracketExpression)		= rnf bracketExpression-	rnf (Predicate showablePredicate)	= rnf showablePredicate+	rnf (Literal m)				= Control.DeepSeq.rnf m+	rnf (AnyOf bracketExpression)		= Control.DeepSeq.rnf bracketExpression+	rnf (NoneOf bracketExpression)		= Control.DeepSeq.rnf bracketExpression+	rnf (Predicate showablePredicate)	= Control.DeepSeq.rnf showablePredicate  -- | True if the specified datum matches. isMatch :: Eq m@@ -133,7 +127,7 @@ isMatch _ Any					= True isMatch datum (Literal literal)			= datum == literal isMatch datum (AnyOf bracketExpression)		= datum `BracketExpression.containsMatch` bracketExpression-isMatch datum (NoneOf bracketExpression)	= not $ datum `isMatch` AnyOf bracketExpression	--This implementation leverages future enhancements to 'AnyOf'.+isMatch datum (NoneOf bracketExpression)	= not $ datum `isMatch` AnyOf bracketExpression	-- This implementation leverages future enhancements to 'AnyOf'. isMatch datum (Predicate showablePredicate)	= ShowablePredicate.predicate showablePredicate datum  -- | The token used to precede a /Perl-style shortcut/, when in the 'String'-form.
src/RegExDot/RegEx.hs view
@@ -1,6 +1,5 @@-{-# LANGUAGE CPP #-} {--	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@@ -86,7 +85,7 @@  	* Test parallel-operation, on a 3 or more processor machine. 	If 'rnf' is less effective than 'rwhnf',-	then the 'NFData' context can be removed,+	then the 'Control.DeepSeq.NFData' context can be removed, 	reducing the requirements imposed on the type-parameter 'a'.  	* Try 'Data.List.Stream' (stream-fusion), a faster drop-in replacement for 'Data.List'; possibly integrated in GHC-6.12.@@ -178,9 +177,10 @@ 	extractDataFromMatchList ) where -import			Control.Applicative((<$>)) import			Control.Arrow((&&&)) import qualified	Control.Arrow+import qualified	Control.DeepSeq+import qualified	Control.Parallel.Strategies import qualified	Data.Char import qualified	Data.Foldable import qualified	Data.List@@ -200,17 +200,7 @@ import qualified	ToolShed.Data.List.Splits import qualified	ToolShed.SelfValidate -#if MIN_VERSION_parallel(3,0,0)-import qualified	Control.Parallel.Strategies-#endif--#ifdef HAVE_DEEPSEQ-import			Control.DeepSeq(NFData, rnf)-#else-import			Control.Parallel.Strategies(NFData, rnf)-#endif--infix 4 +~, =~, /~	--Same as (==) & (/=).+infix 4 +~, =~, /~	-- Same as (==) & (/=).  -- | The type of a /regex/, in which there's no provision for either 'Alternatives' or 'Anchor.Anchor's. type BasicRegEx m	= [Repeatable.Repeatable (Meta.Meta m)]@@ -247,26 +237,26 @@ 	Eq			m, 	Read			m  ) => Read (Alternatives m)	where-	readsPrec _ (' ' : s)	= reads s	--Consume white-space.-	readsPrec _ ('\t' : s)	= reads s	--Consume white-space.+	readsPrec _ (' ' : s)	= reads s	-- Consume white-space.+	readsPrec _ ('\t' : s)	= reads s	-- Consume white-space. 	readsPrec _ s		= case reads s of 		[(extendedRegEx, s1)]	-> case dropWhile Data.Char.isSpace s1 of 			('|' : s2)	-> Control.Arrow.first (transformAlternatives (extendedRegEx :)) `map` reads s2 {-singleton-} 			_		-> [(MkAlternatives [extendedRegEx], s1)]-		_			-> []	--No parse.+		_			-> []	-- No parse.  instance Show m => Show (Alternatives m)	where-	showsPrec _	= foldl (.) (showString "") . Data.List.intersperse (showChar alternativeExtendedRegExSeparatorToken) . map shows . deconstructAlternatives	--Replace the default list-format, with 'egrep'-syntax.+	showsPrec _	= foldl (.) (showString "") . Data.List.intersperse (showChar alternativeExtendedRegExSeparatorToken) . map shows . deconstructAlternatives	-- Replace the default list-format, with 'egrep'-syntax.  instance Consumer.Consumer (Alternatives m)	where 	consumptionProfile	= Consumer.aggregateConsumptionProfilesFromAlternatives . deconstructAlternatives-	starHeight		= Consumer.starHeight . deconstructAlternatives	--Must evaluate all Alternatives to determine best.+	starHeight		= Consumer.starHeight . deconstructAlternatives	-- Must evaluate all Alternatives to determine best.  instance ToolShed.SelfValidate.SelfValidator (Alternatives m)	where 	getErrors	= ToolShed.SelfValidate.getErrors . deconstructAlternatives -instance NFData m => NFData (Alternatives m)	where-	rnf	= rnf . deconstructAlternatives+instance Control.DeepSeq.NFData m => Control.DeepSeq.NFData (Alternatives m)	where+	rnf	= Control.DeepSeq.rnf . deconstructAlternatives  -- | 'Alternatives' can be employed as a simple /capture-group/ as well as a switch, under which circumstances there's no choice amongst multiple 'Alternatives'. isSingletonAlternatives :: Alternatives m -> Bool@@ -303,16 +293,16 @@ 	Read			m, 	ShortcutExpander	m  ) => Read (Pattern m)	where-	readsPrec _ (' ' : s)	= reads s	--Consume white-space.-	readsPrec _ ('\t' : s)	= reads s	--Consume white-space.+	readsPrec _ (' ' : s)	= reads s	-- Consume white-space.+	readsPrec _ ('\t' : s)	= reads s	-- Consume white-space. 	readsPrec _ ('(' : s)	= case {-Alternatives.-} reads s of 		[(alternatives, s1)]	-> case dropWhile Data.Char.isSpace s1 of 			(')' : s2)	-> [(CaptureGroup alternatives, s2)]-			_		-> []	--No parse.-		_			-> []	--No parse.+			_		-> []	-- No parse.+		_			-> []	-- No parse. 	readsPrec _ s		= case reads s of 		[pair]	-> [Control.Arrow.first Require pair]-		_	-> []	--No parse.+		_	-> []	-- No parse.  instance Show m => Show (Pattern m)	where 	showsPrec _ (Require meta)		= shows meta@@ -329,9 +319,9 @@ 	getErrors (Require meta)		= ToolShed.SelfValidate.getErrors meta 	getErrors (CaptureGroup alternatives)	= ToolShed.SelfValidate.getErrors alternatives -instance NFData m => NFData (Pattern m)	where-	rnf (Require meta)		= rnf meta-	rnf (CaptureGroup alternatives)	= rnf alternatives+instance Control.DeepSeq.NFData m => Control.DeepSeq.NFData (Pattern m)	where+	rnf (Require meta)		= Control.DeepSeq.rnf meta+	rnf (CaptureGroup alternatives)	= Control.DeepSeq.rnf alternatives  -- | Convenience-function to build a 'CaptureGroup' from a list of alternative 'ExtendedRegEx's. captureGroup :: [ExtendedRegEx m] -> Pattern m@@ -425,14 +415,14 @@ 	ShortcutExpander	m  ) => Read (ExtendedRegEx m)	where 	readsPrec _ []			= []-	readsPrec _ (' ' : s)		= reads s	--Consume white-space.-	readsPrec _ ('\t' : s)		= reads s	--Consume white-space.+	readsPrec _ (' ' : s)		= reads s	-- Consume white-space.+	readsPrec _ ('\t' : s)		= reads s	-- Consume white-space. 	readsPrec _ ('\\' : c : s)	= [(expand c, s)] 	readsPrec _ s			= case singleton of 		[(extendedRegEx, _)] 			| ToolShed.SelfValidate.isValid extendedRegEx	-> singleton-			| otherwise					-> error $ ToolShed.SelfValidate.getFirstError extendedRegEx	--Parsed OK, but invalid.-		_							-> []								--No parse.+			| otherwise					-> error $ ToolShed.SelfValidate.getFirstError extendedRegEx	-- Parsed OK, but invalid.+		_							-> []								-- No parse. 		where --			singleton :: (Eq m, Meta.ShortcutExpander m, Read m, ShortcutExpander m) => [(ExtendedRegEx m, String)] 			singleton = [@@ -461,9 +451,9 @@  instance Show m => Show (ExtendedRegEx m)	where 	showsPrec _ MkExtendedRegEx {-		bowAnchor	= maybeBowAnchor,	--CAVEAT: this could be 'Nothing' or perversely an 'Anchor.Stern'.+		bowAnchor	= maybeBowAnchor,	-- CAVEAT: this could be 'Nothing' or perversely an 'Anchor.Stern'. 		concatenation	= concatenation',-		sternAnchor	= maybeSternAnchor	--CAVEAT: this could be 'Nothing' or perversely an 'Anchor.Bow'.+		sternAnchor	= maybeSternAnchor	-- CAVEAT: this could be 'Nothing' or perversely an 'Anchor.Bow'. 	} = showsMaybeAnchor maybeBowAnchor . shows concatenation' . showsMaybeAnchor maybeSternAnchor  instance Consumer.Consumer (ExtendedRegEx m)	where@@ -473,12 +463,12 @@ instance ToolShed.SelfValidate.SelfValidator (ExtendedRegEx m)	where 	getErrors	= ToolShed.SelfValidate.getErrors . concatenation -instance NFData m => NFData (ExtendedRegEx m)	where+instance Control.DeepSeq.NFData m => Control.DeepSeq.NFData (ExtendedRegEx m)	where 	rnf MkExtendedRegEx { 		bowAnchor	= maybeBowAnchor, 		concatenation	= concatenation', 		sternAnchor	= maybeSternAnchor-	} = rnf (maybeBowAnchor, concatenation', maybeSternAnchor)+	} = Control.DeepSeq.rnf (maybeBowAnchor, concatenation', maybeSternAnchor)  -- | Drop 'Anchor.Anchor's at both bow & stern of the specified 'ExtendedRegEx'. dock :: Transformation m@@ -551,11 +541,11 @@ 	:: ConsumptionBounds.DataLength	-- ^ The offset by which to shift the position into the input-data at which a match occurred. 	-> Match m			-- ^ The match-structure whose offset is to be shifted. 	-> Match m-shiftMatch i	= (shiftMatchedData i <$>)+shiftMatch i	= (shiftMatchedData i `fmap`)  -- | Extract & concatenate, the 'InputData' from a 'Match'. extractDataFromMatch :: Match m -> InputData m-extractDataFromMatch	= Data.Foldable.foldMap getInputData	--Uses the List-monoid's associative binary operator (++), to concatenate the values returned by the specified function.+extractDataFromMatch	= Data.Foldable.foldMap getInputData	-- Uses the List-monoid's associative binary operator (++), to concatenate the values returned by the specified function.  -- | Extract & concatenate, the 'InputData' from a 'Match'; null if it didn't match any. extractDataFromMatch' :: Maybe (Match m) -> InputData m@@ -574,7 +564,7 @@  -- | Extract & concatenate, the 'InputData', from the 'MatchList'. extractDataFromMatchList :: MatchList m -> InputData m-extractDataFromMatchList	= concatMap extractDataFromMatch	--CAVEAT: too fine-grain for effective data-parallelism.+extractDataFromMatchList	= concatMap extractDataFromMatch	-- CAVEAT: too fine-grain for effective data-parallelism.  -- | At the top-level of an 'ExtendedRegEx', the lack of an 'Anchor.Anchor' allows the 'ExtendedRegEx' to drift away from the corresponding end of the input-data; this data-gap is captured here. type ExternalMatch m	= Maybe (Match m)@@ -596,7 +586,7 @@ 	* One could waste a lot of time trying to consume 'InputData' from the head of a high-'Consumer.starHeight' 'ExtendedRegEx', 	only to find that there's a low-'Consumer.starHeight' tail that can't ever match the 'InputData'; checks this first before delegating. -}-findMatch :: (Eq m, NFData m)+findMatch :: (Eq m, Control.DeepSeq.NFData m) 	=> RegExOpts.RegExOpts (ExtendedRegEx m)	-- ^ The match-options parameterised by the regex against which to match the input data. 	-> InputData m					-- ^ The input data within which to locate a match. 	-> Maybe (MatchList m)@@ -615,19 +605,19 @@ 					CaptureGroup alternatives 						| isSingletonAlternatives alternatives	-> extractLowStarHeightTail {-recurse-} . head $ deconstructAlternatives alternatives 						| otherwise				-> {-non-singleton-} []-					_				-> []	--Zero 'Consumer.StarHeight' would have been detected by 'fromConcatenation'.+					_				-> []	-- Zero 'Consumer.StarHeight' would have been detected by 'fromConcatenation'. 				| otherwise					= []  --		lowStarHeightTail :: Concatenation a 		lowStarHeightTail	= extractLowStarHeightTail extendedRegEx 	in and [ 		ExecutionOptions.checkExistenceOfInelasticTail executionOptions,-		not $ null lowStarHeightTail,	--Prevent infinite recursion.+		not $ null lowStarHeightTail,	-- Prevent infinite recursion. 		reverse originalInputData /~ RegExOpts.mkRegEx MkExtendedRegEx { 			bowAnchor	= Just Anchor.Bow, 			concatenation	= lowStarHeightTail, 			sternAnchor	= Nothing-		} --Check for mismatch with the corresponding tail of 'InputData'.+		} -- Check for mismatch with the corresponding tail of 'InputData'. 	]		= Nothing 	| otherwise	= findMatchSlave originalConcatenation ( 		Consumer.accumulateConsumptionProfiles originalConcatenation@@ -647,28 +637,28 @@  Whilst the only strictly necessary parameters are the lists 'Concatenation' & 'InputData', many ancillary lists derived from them, are also passed by parameter.  These are proportionally reduced on recursion, to avoid the requirement to regenerate them each time they're required. -}-		findMatchSlave :: (Eq m, NFData m)-			=> Concatenation m					--The list of 'RepeatablePattern's from which the regex is constructed.-			-> ConsumptionProfile.AccumulatedConsumptionProfiles	--The capacity-bounds for the consumption of 'InputData', that the 'Concatenation' extending right from any given 'RepeatablePattern', can consume.-			-> [MetaDataList m]					--The set of distinct 'Meta.Meta'-data, in the 'Concatenation extending right from any given 'RepeatablePattern'.-			-> InputData m						--The input data, which will be fed to the 'Concatenation'.-			-> ConsumptionBounds.DataLength				--The length of the previously specified 'InputData'.-			-> [InputData m]					--The set of distinct input data, extending right from any given point.+		findMatchSlave :: (Eq m, Control.DeepSeq.NFData m)+			=> Concatenation m					-- The list of 'RepeatablePattern's from which the regex is constructed.+			-> ConsumptionProfile.AccumulatedConsumptionProfiles	-- The capacity-bounds for the consumption of 'InputData', that the 'Concatenation' extending right from any given 'RepeatablePattern', can consume.+			-> [MetaDataList m]					-- The set of distinct 'Meta.Meta'-data, in the 'Concatenation extending right from any given 'RepeatablePattern'.+			-> InputData m						-- The input data, which will be fed to the 'Concatenation'.+			-> ConsumptionBounds.DataLength				-- The length of the previously specified 'InputData'.+			-> [InputData m]					-- The set of distinct input data, extending right from any given point. 			-> Maybe (MatchList m)-		findMatchSlave [] _ _ [] _ _	= Just []	--Simultaneous exhaustion of the 'Concatenation' of 'RepeatablePattern's & the 'InputData' => success.+		findMatchSlave [] _ _ [] _ _	= Just []	-- Simultaneous exhaustion of the 'Concatenation' of 'RepeatablePattern's & the 'InputData' => success. 		findMatchSlave [] _ _ _ _ _	= Nothing 		findMatchSlave concatenation'@(repeatablePatternHead : concatenationTail) (accumulatedConsumptionProfileHead : accumulatedConsumptionProfilesTail) (distinctMetaDataHead : distinctMetaDataTail) inputData inputDataLength distinctInputData@(distinctInputDataHead : _) 			| not $ inputDataLength `ConsumptionProfile.withinConsumptionBounds` accumulatedConsumptionProfileHead	= Nothing-			| null inputData	= Just $ mkNullMatchFromConcatenation inputDataOffset concatenation'	--Build a 'Match', of null 'InputData'.+			| null inputData	= Just $ mkNullMatchFromConcatenation inputDataOffset concatenation'	-- Build a 'Match', of null 'InputData'. 			| and [-				ExecutionOptions.bypassInputDataForLiberalConsumer executionOptions,			--We may be able to establish success, without evaluating 'inputData' any further than required to determine its length.-				not $ ExecutionOptions.requireMatchList executionOptions,				--Otherwise the precise mapping of the 'inputData' to 'RepeatablePattern's must be determined.-				not $ ConsumptionProfile.hasSpecificRequirement accumulatedConsumptionProfileHead	--Otherwise a match for the specific 'Meta'-data must be found.+				ExecutionOptions.bypassInputDataForLiberalConsumer executionOptions,			-- We may be able to establish success, without evaluating 'inputData' any further than required to determine its length.+				not $ ExecutionOptions.requireMatchList executionOptions,				-- Otherwise the precise mapping of the 'inputData' to 'RepeatablePattern's must be determined.+				not $ ConsumptionProfile.hasSpecificRequirement accumulatedConsumptionProfileHead	-- Otherwise a match for the specific 'Meta'-data must be found. 			] = Just undefined {-shouldn't be evaluated according to 'ExecutionOptions.requireMatchList'-} 			| and [ 				ExecutionOptions.checkForUnconsumableData executionOptions,-				not $ ConsumptionProfile.canConsumeAnything accumulatedConsumptionProfileHead,	--Otherwise the subsequent test will always fail.-				(`isUnconsumableByAnyOf` distinctMetaDataHead) `any` distinctInputDataHead	--Occasionally failure is both inevitable & obvious.+				not $ ConsumptionProfile.canConsumeAnything accumulatedConsumptionProfileHead,	-- Otherwise the subsequent test will always fail.+				(`isUnconsumableByAnyOf` distinctMetaDataHead) `any` distinctInputDataHead	-- Occasionally failure is both inevitable & obvious. 			] = Nothing 			| otherwise	= {-#SCC "findMatchSlave" #-} let 				tailConsumptionProfile :: ConsumptionProfile.ConsumptionProfile@@ -676,10 +666,10 @@ 					ConsumptionProfile.MkConsumptionProfile { 						ConsumptionProfile.consumptionBounds	= (minConsumptionConcatenationTail, maybeMaxConsumptionConcatenationTail) 					}-				 ) = head accumulatedConsumptionProfilesTail	--Extract the aggregate consumption-profile, of the tail of the 'Concatenation'.+				 ) = head accumulatedConsumptionProfilesTail	-- Extract the aggregate consumption-profile, of the tail of the 'Concatenation'.  				maxDataAvailable :: ConsumptionBounds.DataLength-				maxDataAvailable	= inputDataLength - minConsumptionConcatenationTail	--The maximum data available to match 'repeatablePatternHead'.+				maxDataAvailable	= inputDataLength - minConsumptionConcatenationTail	-- The maximum data available to match 'repeatablePatternHead'. 			in if maxDataAvailable < 0 				then Nothing 				else {-inputData is sufficient for concatenationTail-} let@@ -687,7 +677,7 @@ 						Repeatable.base			= base, 						Repeatable.repetitionBounds	= (fewest, most), 						Repeatable.isGreedy		= isGreedy-					} = repeatablePatternHead	--Completely deconstruct the 'Repeatable' at the head of the 'Concatenation'.+					} = repeatablePatternHead	-- Completely deconstruct the 'Repeatable' at the head of the 'Concatenation'. {-  Find the maximum sequence of inputData, preceding the first of the mandatory requirements of 'concatenationTail'.  This enables one to more tightly constrain the maximum number of repetitions of a 'RepeatablePattern',@@ -716,14 +706,14 @@ 								Repeatable.repetitionBounds	= (fewestPeg, _) 							} : pegListTail 						 ) inputData'-							| null remainingInputData && length candidateMatchedInputData < fewestPeg		= Nothing							--Insufficient data to ever match.-							| fewestPeg == 1 || (`Meta.isMatch` metaPeg) `all` tail candidateMatchedInputData	= pegListTail `maximumDataAfterPegs` remainingInputData		--Success => recurse.-							| otherwise										= pegList `maximumDataAfterPegs` tail candidateInputData	--Failed candidate => recurse.+							| null remainingInputData && length candidateMatchedInputData < fewestPeg		= Nothing							-- Insufficient data to ever match.+							| fewestPeg == 1 || (`Meta.isMatch` metaPeg) `all` tail candidateMatchedInputData	= pegListTail `maximumDataAfterPegs` remainingInputData		-- Success => recurse.+							| otherwise										= pegList `maximumDataAfterPegs` tail candidateInputData	-- Failed candidate => recurse. 							where --								candidateInputData, candidateMatchedInputData, remainingInputData :: InputData a 								candidateInputData				= dropWhile (not . (`Meta.isMatch` metaPeg)) inputData' 								(candidateMatchedInputData, remainingInputData)	= fewestPeg `splitAt` candidateInputData-						maximumDataAfterPegs [] inputData'	= Just inputData'	--All the pegs have been matched.+						maximumDataAfterPegs [] inputData'	= Just inputData'	-- All the pegs have been matched. {-  Each 'repeatablePatternHead' can either be a 'Require' or a 'CaptureGroup'.  The former case needs further reduction & we can proceed to construct a 'Tree.Leaf' from any matching 'inputData'.@@ -746,29 +736,29 @@ 									consumedInputDataLength	= length consumedInputData 								in ( 									Tree.Leaf (repeatablePatternHead, inputDataOffset, consumedInputData) :-								) <$> {-apply to Maybe Functor-} findMatchSlave concatenationTail accumulatedConsumptionProfilesTail distinctMetaDataTail unconsumedInputData (+								) `fmap` {-apply to Maybe Functor-} findMatchSlave concatenationTail accumulatedConsumptionProfilesTail distinctMetaDataTail unconsumedInputData ( 									inputDataLength - consumedInputDataLength 								) ( 									consumedInputDataLength `drop` distinctInputData-								) --Recurse, to check whether the 'unconsumedInputData' tail also matches.+								) -- Recurse, to check whether the 'unconsumedInputData' tail also matches. 							 ) $ let 								fewestData, mostData, mostData' :: Repeatable.Repetitions 								fewestData	= {-#SCC "fewestData" #-} case maybeMaxConsumptionConcatenationTail of-									Just m	-> (inputDataLength - m) {- :: ConsumptionBounds.DataLength-} `max` fewest {- :: Repeatable.Repetitions-}	--CAVEAT: conceptually different types.+									Just m	-> (inputDataLength - m) {- :: ConsumptionBounds.DataLength-} `max` fewest {- :: Repeatable.Repetitions-}	-- CAVEAT: conceptually different types. 									_	-> fewest ---								mostData	= length . takeWhile (~= meta) $ (`take` inputData) maxData	--As slow as it is concise.+--								mostData	= length . takeWhile (~= meta) $ (`take` inputData) maxData	-- As slow as it is concise. 								mostData	= {-#SCC "mostData" #-} maxData - measureUnmatchableTail inputData maxData	where 									maxData :: ConsumptionBounds.DataLength 									maxData	= case most of-										Just cap	-> cap {- :: Repeatable.Repetitions-} `min` maxDataAvailable {- :: ConsumptionBounds.DataLength-}	--CAVEAT: conceptually different types.+										Just cap	-> cap {- :: Repeatable.Repetitions-} `min` maxDataAvailable {- :: ConsumptionBounds.DataLength-}	-- CAVEAT: conceptually different types. 										_		-> maxDataAvailable  --									measureUnmatchableTail :: InputData m -> ConsumptionBounds.DataLength -> ConsumptionBounds.DataLength-									measureUnmatchableTail _ 0	= 0						--Have matched all the data.+									measureUnmatchableTail _ 0	= 0						-- Have matched all the data. 									measureUnmatchableTail (a : as) unmatched-										| a `Meta.isMatch` meta	= measureUnmatchableTail as $ pred unmatched	--Recurse.-										| otherwise		= unmatched					--Return the unmatchable tail-length.+										| a `Meta.isMatch` meta	= measureUnmatchableTail as $ pred unmatched	-- Recurse.+										| otherwise		= unmatched					-- Return the unmatchable tail-length. 									measureUnmatchableTail [] _	= error "RegExDot.RegEx.findMatch.findMatchSlave.maybeMatchList.mostData.measureUnmatchableTail:\tdata unexpectedly exhausted." {-  'most' has been extracted from 'repeatablePatternHead',@@ -779,14 +769,14 @@ 								mostData' 									| and [ 										ExecutionOptions.moderateGreed executionOptions,-										isGreedy,		--Otherwise, since the search proceeds from 'fewest' to 'most', the optimal solution is located before backtracking.-										mostData > fewestData	--Otherwise, there's no unbridled greed to moderate.+										isGreedy,		-- Otherwise, since the search proceeds from 'fewest' to 'most', the optimal solution is located before backtracking.+										mostData > fewestData	-- Otherwise, there's no unbridled greed to moderate. 									] = case maximumDataBeforePegs of-										Just maximumDataBeforePegs'	-> mostData `min` length maximumDataBeforePegs'	--Cap upper bound.-										_				-> negate 1	--Guaranteed to be < 'fewestData'.+										Just maximumDataBeforePegs'	-> mostData `min` length maximumDataBeforePegs'	-- Cap upper bound.+										_				-> negate 1	-- Guaranteed to be < 'fewestData'. 									| otherwise {-no requirement for this optimisation-}	= mostData 							 in (-								succ {-fence-post-} mostData' - fewestData	--CAVEAT: possibly <= 0.+								succ {-fence-post-} mostData' - fewestData	-- CAVEAT: possibly <= 0. 							 ) `take` ( 								if isGreedy 									then ToolShed.Data.List.Splits.splitsLeftFrom mostData'@@ -796,15 +786,15 @@ 					CaptureGroup alternatives 						| and [ 							not isGreedy,-							fewest <= 0,	--Zero repetitions permissible.+							fewest <= 0,	-- Zero repetitions permissible. 							Data.Maybe.isJust tailMatch-						] -> zeroRepetitions	--Zero repetitions is the optimal solution, rendering the choice of Alternative irrelevant.+						] -> zeroRepetitions	-- Zero repetitions is the optimal solution, rendering the choice of Alternative irrelevant. 						| and [ 							ExecutionOptions.catchIncompatibleAnchors executionOptions,-							fewest > 1,			--Multiple repetitions.-							minConsumptionAlternatives > 0,	--InputData required.+							fewest > 1,			-- Multiple repetitions.+							minConsumptionAlternatives > 0,	-- InputData required. 							($ extendedRegExAlternatives) `any` [(hasBowAnchor `all`), (hasSternAnchor `all`)]-						]							-> Nothing	--'extendedRegExFromAlternative' requires 'InputData', therefore 'Anchor.Bow' can only pass on the 1st repetition & 'Anchor.Stern' can only pass on the last.+						]							-> Nothing	-- 'extendedRegExFromAlternative' requires 'InputData', therefore 'Anchor.Bow' can only pass on the 1st repetition & 'Anchor.Stern' can only pass on the last. 						| otherwise						-> let {-  We're about to try all repetitions of one Alternative before progressing to the next.@@ -812,13 +802,7 @@  Either way, if the user requires data-capture, then for POSIX-compliance we must perform an exhaustive search of the O(Alternatives ^ Repetitions) permutations for the optimal solution; though the search may be narrowed as we proceed. -} --							matchPairList :: [(Match m, MatchList m)]-							matchPairList	= {-#SCC "matchPairList" #-} Data.Maybe.catMaybes .-#if MIN_VERSION_parallel(3,0,0)-							 concat . Control.Parallel.Strategies.parMap Control.Parallel.Strategies.rseq	--Particularly effective when 'not ExecutionOptions.requireMatchList'.-#else-							 concatMap-#endif-							 (+							matchPairList	= {-#SCC "matchPairList" #-} Data.Maybe.catMaybes . concat . Control.Parallel.Strategies.parMap Control.Parallel.Strategies.rseq {-Particularly effective when 'not ExecutionOptions.requireMatchList' -} ( --								:: ExtendedRegEx m -> [Maybe (Match m, MatchList m)] 								\extendedRegExFromAlternative@MkExtendedRegEx { 									concatenation	= concatenationFromAlternative@@ -836,10 +820,10 @@ 									if ExecutionOptions.abortTrialRepetitionsOnZeroConsumption executionOptions && Data.Maybe.isNothing most {-constrained only by 'inputDataLength'-} 										then {-#SCC "abortTrialRepetitionsOnZeroConsumption" #-} ToolShed.Data.List.takeUntil $ \maybeMatchPair -> case maybeMatchPair of 											Just (match, _)	-> ($ Tree.pop match) `all` [-												(>= fewest) . length,			--Must achieve 'Repeatable.getFewest', regardless of data-consumption.-												null . extractDataFromMatchList . last	--If the n-th repetition consumed nothing, so will the (n + 1)-th.+												(>= fewest) . length,			-- Must achieve 'Repeatable.getFewest', regardless of data-consumption.+												null . extractDataFromMatchList . last	-- If the n-th repetition consumed nothing, so will the (n + 1)-th. 											 ]-											_		-> False			--Failure with n repetitions, doesn't preclude success with n + 1.+											_		-> False			-- Failure with n repetitions, doesn't preclude success with n + 1. 										else {-optimisation not required-} id 								) . ( --									:: Maybe (Match m, MatchList m) -> Maybe (Match m, MatchList m)@@ -853,14 +837,14 @@ -} 										then {-#SCC "abortTrialRepetitionsOnInherentFailure" #-} case maybeMatchPairList of 											(Nothing {-failed attempt-} : _ {-subsequent attempt worth bypassing-} : _)	-> if (-												minConsumptionConcatenationFromAlternative == 0	--Can delegate consumption of unconsumable data to the infallible tail => unprovable culpability.+												minConsumptionConcatenationFromAlternative == 0	-- Can delegate consumption of unconsumable data to the infallible tail => unprovable culpability. 											 ) || inputData =~ RegExOpts.mkRegEx MkExtendedRegEx { 												bowAnchor	= Just Anchor.Bow,-												concatenation	= concatenationFromAlternative ++ [anyDatum ^#-> minConsumptionConcatenationTail],	--Infallible tail.+												concatenation	= concatenationFromAlternative ++ [anyDatum ^#-> minConsumptionConcatenationTail],	-- Infallible tail. 												sternAnchor	= Just Anchor.Stern 											 } 												then maybeMatchPairList-												else []	--Abandon further repetitions of 'Alternatives'.+												else []	-- Abandon further repetitions of 'Alternatives'. 											_ {-Alternative is OK, or there's no subsequent attempt to bypass-}		-> maybeMatchPairList 										else {-optimisation not required-} maybeMatchPairList 								) . map (@@ -870,12 +854,12 @@ 											then ( 												shiftMatch inputDataOffset . Tree.Node . ( 													: replicate (-														pred repetitions	--Typically degenerates to zero, since anchored sub-expressions aren't normally repeatable.+														pred repetitions	-- Typically degenerates to zero, since anchored sub-expressions aren't normally repeatable. 													) (-														mkNullMatchFromExtendedRegEx 0 extendedRegExFromAlternative	--Other Alternatives may be available & suitable.-													) --Repeated null match may, lacking other suitable Alternatives, correspond to this stern-anchored ExtendedRegEx, so data must be consumed before them.+														mkNullMatchFromExtendedRegEx 0 extendedRegExFromAlternative	-- Other Alternatives may be available & suitable.+													) -- Repeated null match may, lacking other suitable Alternatives, correspond to this stern-anchored ExtendedRegEx, so data must be consumed before them. 												) &&& const (mkNullMatchFromConcatenation inputDataOffset concatenationTail)-											) <$> findMatch regExOpts { RegExOpts.regEx = extendedRegExFromAlternative } inputData	--Recurse, either consuming all inputData or failing.+											) `fmap` findMatch regExOpts { RegExOpts.regEx = extendedRegExFromAlternative } inputData	-- Recurse, either consuming all inputData or failing. 											else Nothing 										else {-no Anchor.Stern-} let {-@@ -896,10 +880,10 @@ 												| repetitions == 1	= ( 													Control.Arrow.first ( 														Tree.Node . return {-to List-monad-}-													) . splitAt components,	--Bisect the 'MatchList', into the part resulting from the Alternative, & that for 'concatenationTail'.+													) . splitAt components,	-- Bisect the 'MatchList', into the part resulting from the Alternative, & that for 'concatenationTail'. 													consumptionProfileConcatenationFromAlternative, 													concatenationFromAlternative-												) --Both tuples below, can degenerate to this simple case; it isn't a fundamentally different algorithm.+												) -- Both tuples below, can degenerate to this simple case; it isn't a fundamentally different algorithm. 												| and [ 													ExecutionOptions.unrollRepeatedSingletonAlternative executionOptions, 													isSingletonAlternative,@@ -909,37 +893,37 @@ 														Tree.Node . ToolShed.Data.List.chunk components 													) . splitAt ( 														components * repetitions-													), --Bisect the 'MatchList', into the part resulting from (Alternative){n}, & that for 'concatenationTail'.+													), -- Bisect the 'MatchList', into the part resulting from (Alternative){n}, & that for 'concatenationTail'. 													concat $ replicate repetitions consumptionProfileConcatenationFromAlternative,-													concat $ replicate repetitions concatenationFromAlternative	--Expand all repetitions of the single alternative.+													concat $ replicate repetitions concatenationFromAlternative	-- Expand all repetitions of the single alternative. 												) 												| otherwise {-choice of Alternatives or has Anchor.Bow-}	=  let 													remainingRepetitions :: Repeatable.Repetitions-													remainingRepetitions	= pred repetitions	--Expand just the first repetition of the set of 'Alternatives'.+													remainingRepetitions	= pred repetitions	-- Expand just the first repetition of the set of 'Alternatives'.  --													singletonRepeatable :: RepeatablePattern a 													singletonRepeatable	= Repeatable.toSingleton repeatablePatternHead 												in ( 													Control.Arrow.first ( 														Tree.Node . uncurry (:) . Control.Arrow.second (-															concatMap Tree.pop		--Amalgamate the repeated singleton 'MatchList's.-														) . splitAt components			--Bisect first 'MatchList', into the part resulting from 'concatenationFromAlternative', & that for 'replicate remainingRepetitions'.+															concatMap Tree.pop		-- Amalgamate the repeated singleton 'MatchList's.+														) . splitAt components			-- Bisect first 'MatchList', into the part resulting from 'concatenationFromAlternative', & that for 'replicate remainingRepetitions'. 													) . splitAt (-														components + remainingRepetitions	--Bisect the 'MatchList', into the part resulting from (Alternatives){n}, & that for 'concatenationTail'.+														components + remainingRepetitions	-- Bisect the 'MatchList', into the part resulting from (Alternatives){n}, & that for 'concatenationTail'. 													), 													consumptionProfileConcatenationFromAlternative ++ replicate remainingRepetitions (Consumer.consumptionProfile singletonRepeatable),-													concatenationFromAlternative {-expand 1st repetition-} ++ replicate remainingRepetitions {-potentially zero-} singletonRepeatable	--Enumerate all remaining repetitions of ANY Alternative; a different Alternative can match for each repetition.+													concatenationFromAlternative {-expand 1st repetition-} ++ replicate remainingRepetitions {-potentially zero-} singletonRepeatable	-- Enumerate all remaining repetitions of ANY Alternative; a different Alternative can match for each repetition. 												)-									in {-#SCC "collater" #-} collater <$> {-apply to Maybe Functor-} findMatchSlave (+									in {-#SCC "collater" #-} collater `fmap` {-apply to Maybe Functor-} findMatchSlave ( 										expandedConcatenationPrefix ++ concatenationTail 									) ( 										ConsumptionProfile.accumulateFrom tailConsumptionProfile {-initial value-} consumptionProfileExpandedConcatenationPrefix ++ tail accumulatedConsumptionProfilesTail 									) ( 										accumulateDistinctMetaDataFrom (head distinctMetaDataTail) {-initial value-} expandedConcatenationPrefix ++ tail distinctMetaDataTail-									) inputData inputDataLength distinctInputData	--Recurse to get 'Maybe (MatchList a)'.-								) $ if Repeatable.isPrecise repeatablePatternHead	--These are frequently generated by the previous recursion, as a trial expansion of an Alternative.+									) inputData inputDataLength distinctInputData	-- Recurse to get 'Maybe (MatchList a)'.+								) $ if Repeatable.isPrecise repeatablePatternHead	-- These are frequently generated by the previous recursion, as a trial expansion of an Alternative. 									then if ExecutionOptions.validateMinConsumptionOfAlternatives executionOptions && maxDataAvailable < fewest * minConsumptionAlternatives-										then []	--Failure is inevitable.+										then []	-- Failure is inevitable. 										else [fewest] 									else {-imprecise range-} let {-@@ -953,48 +937,48 @@ 											then fewest 											else {-no unlimited capacities-} let 												minDataAvailable, maxConsumptionAlternatives :: ConsumptionBounds.DataLength-												minDataAvailable		= inputDataLength - Data.Maybe.fromJust maybeMaxConsumptionConcatenationTail	--CAVEAT: can be negative.+												minDataAvailable		= inputDataLength - Data.Maybe.fromJust maybeMaxConsumptionConcatenationTail	-- CAVEAT: can be negative. 												maxConsumptionAlternatives	= Data.Maybe.fromJust maybeMaxConsumptionAlternatives 											in if isSingletonAlternative-												then if maxConsumptionAlternatives == 0							--Denominator.-													then {-sole Alternative can't consume anything ?!-} if minDataAvailable <= 0	--Numerator.-														then {-tail may consume all data-} fewest	--Repeat to meet the minimum requirement.-														else {-unconsumable data-} maxBound		--Failure is inevitable.+												then if maxConsumptionAlternatives == 0							-- Denominator.+													then {-sole Alternative can't consume anything ?!-} if minDataAvailable <= 0	-- Numerator.+														then {-tail may consume all data-} fewest	-- Repeat to meet the minimum requirement.+														else {-unconsumable data-} maxBound		-- Failure is inevitable. 													else {-non-zero => can divide-} max fewest $ minDataAvailable /+ maxConsumptionAlternatives 												else {-choice of Alternatives-} let 													minDataAvailable' :: ConsumptionBounds.DataLength-													minDataAvailable'	= minDataAvailable - Data.Maybe.fromJust maybeMaxConsumptionConcatenationFromAlternative	--CAVEAT: potentially negative.-												in if maxConsumptionAlternatives == 0						--Denominator.-													then {-no Alternative can consume anything-} if minDataAvailable' <= 0	--Numerator.-														then {-zero unconsumable data-} fewest	--Repeat to meet the minimum requirement.-														else {-unconsumable data-} maxBound	--Failure is inevitable.+													minDataAvailable'	= minDataAvailable - Data.Maybe.fromJust maybeMaxConsumptionConcatenationFromAlternative	-- CAVEAT: potentially negative.+												in if maxConsumptionAlternatives == 0						-- Denominator.+													then {-no Alternative can consume anything-} if minDataAvailable' <= 0	-- Numerator.+														then {-zero unconsumable data-} fewest	-- Repeat to meet the minimum requirement.+														else {-unconsumable data-} maxBound	-- Failure is inevitable. 													else {-non-zero => can divide-} max fewest . succ {-account for expanded instance-} $ minDataAvailable' /+ maxConsumptionAlternatives  										mostAlternatives	= {-#SCC "mostAlternatives" #-} case most of-											Just cap	-> cap `min` mostPermissibleRepetitions	--Create a ceiling above which the calculated number of permissible repetitions can't rise.+											Just cap	-> cap `min` mostPermissibleRepetitions	-- Create a ceiling above which the calculated number of permissible repetitions can't rise. 											_		-> mostPermissibleRepetitions 											where 												mostPermissibleRepetitions :: Repeatable.Repetitions 												mostPermissibleRepetitions-													| isSingletonAlternative		= if minConsumptionAlternatives == 0							--Denominator.-														then {-sole Alternative can consume zero data-} if maxDataAvailable == 0	--Numerator.-															then {-zero data available-} fewest		--Repeat to meet the minimum requirement.-															else {-data available-} maxDataAvailable	--Either each repetition consumes something, or (n - 1) repetitions is a better solution.-														else {-non-zero => can divide-} maxDataAvailable `div` minConsumptionAlternatives	--Divide & round down.+													| isSingletonAlternative		= if minConsumptionAlternatives == 0							-- Denominator.+														then {-sole Alternative can consume zero data-} if maxDataAvailable == 0	-- Numerator.+															then {-zero data available-} fewest		-- Repeat to meet the minimum requirement.+															else {-data available-} maxDataAvailable	-- Either each repetition consumes something, or (n - 1) repetitions is a better solution.+														else {-non-zero => can divide-} maxDataAvailable `div` minConsumptionAlternatives	-- Divide & round down. 													| otherwise {-choice of Alternatives-}	= 1 {-account for instance expanded as 'concatenationFromAlternative'-} + let 														maxDataAvailable' :: ConsumptionBounds.DataLength-														maxDataAvailable'	= maxDataAvailable - minConsumptionConcatenationFromAlternative	--CAVEAT: potentially negative.-													in if minConsumptionAlternatives == 0							--Denominator.-														then {-@ least one Alternative can consume zero-} if maxDataAvailable' == 0	--Numerator.-															then {-zero data available $-} pred fewestAlternatives	--Repeat as required. CAVEAT: an annoying dependency, which prevents parallel-evaluation.+														maxDataAvailable'	= maxDataAvailable - minConsumptionConcatenationFromAlternative	-- CAVEAT: potentially negative.+													in if minConsumptionAlternatives == 0							-- Denominator.+														then {-@ least one Alternative can consume zero-} if maxDataAvailable' == 0	-- Numerator.+															then {-zero data available $-} pred fewestAlternatives	-- Repeat as required. CAVEAT: an annoying dependency, which prevents parallel-evaluation. 															else {-data available-} if and [-																False,	--The cost outweighs the small infrequent dividend.+																False,	-- The cost outweighs the small infrequent dividend. 																minConsumptionConcatenationFromAlternative == 0, 																maxDataAvailable > fewest-															] --If 'fewest' can be met, without unconsuming repetitions of 'concatenationFromAlternative', then stop short of permitting it.-																then pred maxDataAvailable	--Any greater, & one repetition (possibly that currently expanded) must needlessly consume nothing.-																else maxDataAvailable'		--Either all n repetitions consumes something, or (n - 1) is a better solution.-														else {-non-zero => can divide-} maxDataAvailable' `div` minConsumptionAlternatives	--Divide & round down.+															] -- If 'fewest' can be met, without unconsuming repetitions of 'concatenationFromAlternative', then stop short of permitting it.+																then pred maxDataAvailable	-- Any greater, & one repetition (possibly that currently expanded) must needlessly consume nothing.+																else maxDataAvailable'		-- Either all n repetitions consumes something, or (n - 1) is a better solution.+														else {-non-zero => can divide-} maxDataAvailable' `div` minConsumptionAlternatives	-- Divide & round down. {-  'most' has been extracted from 'repeatablePatternHead',  & reduced according to the number of times it can fit into the maximum available data, to form 'mostAlternatives',@@ -1004,16 +988,16 @@ -} 										mostAlternatives'	= {-#SCC "mostAlternatives'" #-} if and [ 											ExecutionOptions.moderateGreed executionOptions,-											mostAlternatives > fewestAlternatives,	--Otherwise, there's no unbridled greed to moderate.-											minConsumptionAlternatives > 0		--Otherwise, any number of repetitions can occur without necessarily triggering back-tracking.+											mostAlternatives > fewestAlternatives,	-- Otherwise, there's no unbridled greed to moderate.+											minConsumptionAlternatives > 0		-- Otherwise, any number of repetitions can occur without necessarily triggering back-tracking. 										 ] 											then case maximumDataBeforePegs of 												Just maximumDataBeforePegs'	-> mostAlternatives `min` ( 													length maximumDataBeforePegs' `div` minConsumptionAlternatives-												 ) --Cap upper bound.-												_				-> negate 1	--Guaranteed to be < 'fewestAlternatives'.+												 ) -- Cap upper bound.+												_				-> negate 1	-- Guaranteed to be < 'fewestAlternatives'. 											else {-no requirement for this optimisation-} mostAlternatives-									in [fewestAlternatives .. mostAlternatives']	--The permissible repetition-range of any Alternative, constrained by the amount of data available, after subtracting fixed consumption-requirements.+									in [fewestAlternatives .. mostAlternatives']	-- The permissible repetition-range of any Alternative, constrained by the amount of data available, after subtracting fixed consumption-requirements. 							 ) . ( 								if ExecutionOptions.permitReorderingOfAlternatives executionOptions {-@@ -1025,18 +1009,18 @@ -} 									then Data.List.sortBy $ Data.Ord.comparing ( 										Consumer.starHeight &&& safeReciprocal . (fromIntegral :: ConsumptionBounds.DataLength -> Rational) . Consumer.getFewest-									) --Firstly increasing complexity, then decreasing minimum data-capacity, otherwise stable.+									) -- Firstly increasing complexity, then decreasing minimum data-capacity, otherwise stable. 									else id 							 ) $ filter ( 								\e	-> (-									not (hasBowAnchor e) || inputDataOffset == 0			--Necessary & sufficient.+									not (hasBowAnchor e) || inputDataOffset == 0			-- Necessary & sufficient. 								) && (-									not (hasSternAnchor e) || minConsumptionConcatenationTail == 0	--Necessary but insufficient, since though minimum consumption is zero, maximum isn't necessarily.+									not (hasSternAnchor e) || minConsumptionConcatenationTail == 0	-- Necessary but insufficient, since though minimum consumption is zero, maximum isn't necessarily. 								) 							 ) extendedRegExAlternatives 						in if null matchPairList 							then if fewest <= 0-								then zeroRepetitions	--Which might still fail, depending on 'tailMatch'.+								then zeroRepetitions	-- Which might still fail, depending on 'tailMatch'. 								else {-zero repetitions isn't permissible-} Nothing 							else {-at least one Alternative matched-} {-#SCC "selectAlternative" #-} Just . uncurry (:) {-re-join head & tail-} $ ( {-@@ -1048,27 +1032,28 @@ 								if ExecutionOptions.useFirstMatchAmongAlternatives executionOptions || length matchPairList == 1 									then head 									else snd {-remove prepended selection-criterion-} . Data.List.maximumBy {-select the best match-} (-										Data.Ord.comparing fst	--Compare using only the criterion, not the result from which it was derived.+										Data.Ord.comparing fst	-- Compare using only the criterion, not the result from which it was derived. 									) . map ( 										( {-  If the primary selection-criterion doesn't resolve the choice between candidate 'Match'es, I employ these ad-hoc criteria.-* Fewer repetitions are preferred, which discourages the capture of null lists of 'InputData'. -* Within the 'MatchedData', from which a candidate 'Match' is ultimately composed, consumption of 'InputData' beyond 'Repeatable.getFewest' by 'Repeatable.isGreedy' 'RepeatablePattern's, is preferred to non-greedy ones.+	* Fewer repetitions are preferred, which discourages the capture of null lists of 'InputData'. -* The consumption on each successive repetition is compared between candidate 'Match'es (which are now known to have used an equal number of repetitions);-this causes the data-consumption to flow towards earlier repetitions for greedy capture-groups, & towards later repetitions in non-greedy ones,-thus mimicking the behaviour of the unrolled repetition.+	* Within the 'MatchedData', from which a candidate 'Match' is ultimately composed, consumption of 'InputData' beyond 'Repeatable.getFewest' by 'Repeatable.isGreedy' 'RepeatablePattern's, is preferred to non-greedy ones. -* PS: more precise criteria are defined in <http://www2.research.att.com/~gsf/testregex/re-interpretation.html>.+	* The consumption on each successive repetition is compared between candidate 'Match'es (which are now known to have used an equal number of repetitions);+	this causes the data-consumption to flow towards earlier repetitions for greedy capture-groups, & towards later repetitions in non-greedy ones,+	thus mimicking the behaviour of the unrolled repetition.++	* PS: more precise criteria are defined in <http://www2.research.att.com/~gsf/testregex/re-interpretation.html>. -} 											\match -> let 												dataLengthCriterion :: InputData m -> Rational 												dataLengthCriterion	= ( 													if isGreedy 														then id-														else safeReciprocal	--Prefer less data.+														else safeReciprocal	-- Prefer less data. 												 ) . fromIntegral . length  --												matchLists :: [MatchList m]@@ -1076,7 +1061,7 @@ 											in ( 												dataLengthCriterion $ extractDataFromMatch match, 												if ExecutionOptions.preferFewerRepeatedAlternatives executionOptions-													then safeReciprocal . fromIntegral $ length matchLists :: Rational+													then safeReciprocal . toRational $ length matchLists 													else 0, 												if ExecutionOptions.preferAlternativesWhichFeedTheGreedy executionOptions 													then let@@ -1099,14 +1084,14 @@ 												if ExecutionOptions.preferAlternativesWhichMimickUnrolling executionOptions 													then map (dataLengthCriterion . extractDataFromMatchList) matchLists 													else []-											) --Create a tuple of selection-criteria, for simultaneous assessment.-										) . fst {-focus the choice on the Alternatives-} &&& id	--Prepend a selection-criterion to each result.+											) -- Create a tuple of selection-criteria, for simultaneous assessment.+										) . fst {-focus the choice on the Alternatives-} &&& id	-- Prepend a selection-criterion to each result. 									) 							) matchPairList 						where --							tailMatch, zeroRepetitions :: Maybe (MatchList m)-							tailMatch	= findMatchSlave concatenationTail accumulatedConsumptionProfilesTail distinctMetaDataTail inputData inputDataLength distinctInputData	--Recurse.-							zeroRepetitions	= (Tree.Node [] :) <$> {-apply to Maybe Functor-} tailMatch	--Prepend a null 'MatchList'.+							tailMatch	= findMatchSlave concatenationTail accumulatedConsumptionProfilesTail distinctMetaDataTail inputData inputDataLength distinctInputData	-- Recurse.+							zeroRepetitions	= (Tree.Node [] :) `fmap` {-apply to Maybe Functor-} tailMatch	-- Prepend a null 'MatchList'.  --							extendedRegExAlternatives :: [ExtendedRegEx m] 							extendedRegExAlternatives	= Data.List.nub $ deconstructAlternatives alternatives@@ -1116,7 +1101,7 @@  							minConsumptionAlternatives	:: ConsumptionBounds.DataLength 							maybeMaxConsumptionAlternatives	:: Maybe ConsumptionBounds.DataLength-							(minConsumptionAlternatives, maybeMaxConsumptionAlternatives)	= Consumer.getConsumptionBounds alternatives	--Independent of the choice of Alternative.+							(minConsumptionAlternatives, maybeMaxConsumptionAlternatives)	= Consumer.getConsumptionBounds alternatives	-- Independent of the choice of Alternative. 			where 				inputDataOffset :: ConsumptionBounds.DataLength 				inputDataOffset	= originalInputDataLength - inputDataLength@@ -1128,18 +1113,20 @@ 	* CAVEAT: much more expensive then '=~': in /ghci/, 'Just' can be observed to be printed /long/ before the 'MatchList' from which 'Result' is constructed, 	as the lazy algorithm finds the first solution, but not yet necessarily the optimal solution, amongst 'Alternatives'. -}-(+~) :: (Eq m, NFData m)+(+~) :: (Eq m, Control.DeepSeq.NFData m) 	=> InputData m					-- ^ The input data within which to locate a match. 	-> RegExOpts.RegExOpts (ExtendedRegEx m)	-- ^ The match-options parameterised by the regex against which to match the input data. 	-> Result m inputData +~ regExOpts	= (-	if hasBowAnchor' then Nothing else head <$> maybeMatchList,	--Record the first 'Match', consumed in the absence of a top-level 'Anchor.Bow'.-	(-		if hasBowAnchor' then id else tail			--Remove the first 'Match', since this wasn't consumed by the 'Concatenation'.-	) . (-		if hasSternAnchor' then id else init			--Remove the last 'Match', since this wasn't consumed by the 'Concatenation'.-	) <$> maybeMatchList,-	if hasSternAnchor' then Nothing else last <$> maybeMatchList	--Record the last 'Match', consumed in the absence of a top-level 'Anchor.Stern'.+	if hasBowAnchor' then Nothing else fmap head maybeMatchList,	-- Record the first 'Match', consumed in the absence of a top-level 'Anchor.Bow'.+	fmap (+		(+			if hasBowAnchor' then id else tail			-- Remove the first 'Match', since this wasn't consumed by the 'Concatenation'.+		) . (+			if hasSternAnchor' then id else init			-- Remove the last 'Match', since this wasn't consumed by the 'Concatenation'.+		)+	) maybeMatchList,+	if hasSternAnchor' then Nothing else fmap last maybeMatchList	-- Record the last 'Match', consumed in the absence of a top-level 'Anchor.Stern'.  ) where --	extendedRegEx :: ExtendedRegEx a 	extendedRegEx	= RegExOpts.regEx regExOpts@@ -1160,14 +1147,14 @@ 	the discovery of /any/ solution is sufficient to generate the return-value; 	lazy-evaluation avoids the requirement to identify the irrelevant optimal solution. -}-(=~) :: (Eq m, NFData m)+(=~) :: (Eq m, Control.DeepSeq.NFData m) 	=> InputData m					-- ^ The input data within which to locate a match. 	-> RegExOpts.RegExOpts (ExtendedRegEx m)	-- ^ The match-options parameterised by the regex against which to match the input data. 	-> Bool inputData =~ regExOpts	= Data.Maybe.isJust $ fmap drift (RegExOpts.setVerbose False regExOpts) `findMatch` inputData  -- | Pattern-mismatch operator.-(/~) :: (Eq m, NFData m)+(/~) :: (Eq m, Control.DeepSeq.NFData m) 	=> InputData m					-- ^ The input data within which to locate a match. 	-> RegExOpts.RegExOpts (ExtendedRegEx m)	-- ^ The match-options parameterised by the regex against which to match the input data. 	-> Bool@@ -1191,21 +1178,21 @@ 	* CAVEAT: this is an awful concept, and therefore intended for internal use only. -} safeReciprocal :: (Eq f, Fractional f) => f -> f-safeReciprocal 0	= fromIntegral (maxBound :: Int)	--Handle divide-by-zero error.+safeReciprocal 0	= fromIntegral (maxBound :: Int)	-- Handle divide-by-zero error. safeReciprocal f	= recip f -infixl 7 /+	--Same as (/).+infixl 7 /+	-- Same as (/).  {- | 	* Integral division, with any fractional remainder rounded-up.  	* A rather dubious requirement, so internal use only. -}---(/+) :: Integral i => i -> i -> i+-- (/+) :: Integral i => i -> i -> i (/+) 	:: Int	-- ^ Numerator. 	-> Int	-- ^ Denominator.-	-> Int	--10% faster in unoptimised code, & more in optimised.+	-> Int	-- 10% faster in unoptimised code, & more in optimised. _ /+ 0				= error "RegExDot.RegEx.(/+):\tzero denominator => infinity"---numerator /+ denominator	= ceiling ((fromIntegral numerator / fromIntegral denominator) :: Double)-numerator /+ denominator	= uncurry (+) . Control.Arrow.second signum $ quotRem numerator denominator	--Slightly faster.+-- numerator /+ denominator	= ceiling ((fromIntegral numerator / fromIntegral denominator) :: Double)+numerator /+ denominator	= uncurry (+) . Control.Arrow.second signum $ quotRem numerator denominator	-- Slightly faster.
src/RegExDot/Repeatable.hs view
@@ -1,6 +1,5 @@-{-# LANGUAGE CPP #-} {--	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@@ -80,8 +79,10 @@ 	hasPreciseBounds ) where +import Prelude hiding ((<$>), (<*>))	-- The "Prelude" from 'base-4.8' exports this symbol. import			Control.Applicative((<$>), (<*>)) import			Control.Arrow((***))+import qualified	Control.DeepSeq import qualified	Data.List import qualified	RegExDot.Consumer		as Consumer import qualified	RegExDot.ConsumptionProfile	as ConsumptionProfile@@ -90,13 +91,7 @@ import qualified	ToolShed.Data.Pair import qualified	ToolShed.SelfValidate -#ifdef HAVE_DEEPSEQ-import			Control.DeepSeq(NFData, rnf)-#else-import			Control.Parallel.Strategies(NFData, rnf)-#endif--infix 6 ^#->#, ^#->#?, ^#->, ^#->?, ^#	--A notch tighter than "DSL"s binary operators.+infix 6 ^#->#, ^#->#?, ^#->, ^#->?, ^#	-- A notch tighter than "DSL"s binary operators.  -- | A number of repetitions. type Repetitions	= Int@@ -129,7 +124,7 @@ -- | Builds a parser for a specification of the number of permissible instances of the specified polymorphic parameter. repeatableParser :: a -> Parsec.Parser (Repeatable a) repeatableParser b	= Parsec.option (-	one b	--The default; there's no concept of greediness here.+	one b	-- The default; there's no concept of greediness here.  ) $ do 	repeatable	<- Parsec.choice [ 		(Parsec.char oneOrMoreToken <?> "Repeatable.oneOrMoreToken " ++ show oneOrMoreToken)	>> return {-to ParsecT-monad-} (oneOrMore b),@@ -139,7 +134,7 @@ 			do 				fewest	<- Parsec.spaces >> (read <$> Parsec.many1 Parsec.digit <?> "Repetition-range minimum") 				most	<- Parsec.spaces >> Parsec.option (-					Just fewest	--The default.+					Just fewest	-- The default. 				 ) ( 					do 						i	<- (@@ -157,12 +152,12 @@  	g	<- Parsec.option True {-the default-} $ (Parsec.char nonGreedyToken <?> "Repeatable.nonGreedyToken " ++ show nonGreedyToken) >> return {-to ParsecT-monad-} False -	return {-to ParsecT-monad-} repeatable { isGreedy = g }	--Correct prior assumption.+	return {-to ParsecT-monad-} repeatable { isGreedy = g }	-- Correct prior assumption.  instance Read a => Read (Repeatable a)	where 	readsPrec _ s	= case reads s {-first, read the base-type-} of 		[(base', s1)]	-> (error . ("readsPrec Repeatable:\tparse-error; " ++) . show) `either` return $ Parsec.parse ((,) <$> repeatableParser base' <*> Parsec.getInput) "Repeatable" s1-		_		-> []	--No parse.+		_		-> []	-- No parse.  {- | 	* A 'ShowS'-function for the suffix, denoting the permissible repetitions, of 'base'.@@ -179,15 +174,15 @@ 		(1, Nothing)		-> showChar oneOrMoreToken 		(fewest, Nothing)	-> showRange $ shows fewest . showChar rangeSeparatorToken 		(0, Just 1)		-> showChar zeroOrOneToken-		(1, Just 1)		-> id	--CAVEAT: since there's no explicit repetition-operator, the non-greedy modifier can't be appended.+		(1, Just 1)		-> id	-- CAVEAT: since there's no explicit repetition-operator, the non-greedy modifier can't be appended. 		(fewest, Just most)	-> showRange $ if fewest == most-			then shows fewest	--Single-valued range.+			then shows fewest	-- Single-valued range. 			else shows fewest . showChar rangeSeparatorToken . shows most  ) . if ($ repeatable) `any` [isGreedy, isPrecise] {-without a range of possibilities, non-greediness is irrelevant-} 	then id-	else showChar nonGreedyToken	--This can only be appended, if there a previous repetition-operator for it to modify.+	else showChar nonGreedyToken	-- This can only be appended, if there a previous repetition-operator for it to modify. ---Replicate the syntax, for repetition, as used in a POSIX-standard /regex/.+-- Replicate the syntax, for repetition, as used in a POSIX-standard /regex/. instance Show a => Show (Repeatable a)	where 	showsPrec _ repeatable	= shows (base repeatable) . showSuffix repeatable @@ -196,7 +191,7 @@ 		base			= b, 		repetitionBounds	= (fewest, most) 	} = baseConsumptionProfile {-		ConsumptionProfile.consumptionBounds	= (fewest *) *** ((*) <$> most <*>) $ ConsumptionProfile.consumptionBounds baseConsumptionProfile	--CAVEAT: special cases exist, where one or both halves of this calculation degenerate to a simpler form, but special treatment, in an attempt to improve performance, proved counterproductive.+		ConsumptionProfile.consumptionBounds	= (fewest *) *** ((*) <$> most <*>) $ ConsumptionProfile.consumptionBounds baseConsumptionProfile	-- CAVEAT: special cases exist, where one or both halves of this calculation degenerate to a simpler form, but special treatment, in an attempt to improve performance, proved counterproductive. 	} where 		baseConsumptionProfile :: ConsumptionProfile.ConsumptionProfile 		baseConsumptionProfile	= Consumer.consumptionProfile b@@ -212,7 +207,7 @@ 		repetitionBounds	= (fewest, most), 		isGreedy		= g 	}-		| not $ ToolShed.SelfValidate.isValid b	= ToolShed.SelfValidate.getErrors b	--Delegate.+		| not $ ToolShed.SelfValidate.isValid b	= ToolShed.SelfValidate.getErrors b	-- Delegate. 		| otherwise				= ToolShed.SelfValidate.extractErrors [ 			(fewest < 0, "Negative fewest=" ++ show fewest ++ "."), 			(@@ -222,18 +217,18 @@ 				"Invalid repetition-range; '" ++ show (fewest, most) ++ "'." 			), ( 				not g && case most of-					Just m	-> fewest >= m	--There ought to be potential for non-greediness, where specified: the converse isn't true, since greediness isn't explicit, & may not have been wanted.+					Just m	-> fewest >= m	-- There ought to be potential for non-greediness, where specified: the converse isn't true, since greediness isn't explicit, & may not have been wanted. 					_	-> False, 				"Invalid non-greedy repetition-range; '" ++ show (fewest, most) ++ "'." 			) 		] -instance NFData a => NFData (Repeatable a)	where+instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Repeatable a)	where 	rnf MkRepeatable { 		base			= b, 		repetitionBounds	= r, 		isGreedy		= g-	} = rnf (b, r, g)+	} = Control.DeepSeq.rnf (b, r, g)  -- | Mutator. setNonGreedy :: Repeatable a -> Repeatable a
src/RegExDot/ShowablePredicate.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {- 	Copyright (C) 2010 Dr. Alistair Ward @@ -32,11 +31,7 @@ 	) ) where -#ifdef HAVE_DEEPSEQ-import	Control.DeepSeq(NFData, rnf)-#else-import	Control.Parallel.Strategies(NFData, rnf)-#endif+import qualified	Control.DeepSeq  -- | An arbitrary polymorphic predicate function. type Predicate a	= a -> Bool@@ -51,8 +46,8 @@ 	showsPrec _	= showString . name  instance Eq (ShowablePredicate a)	where-	l == r	= name l == name r	--Ignore 'predicate'.+	l == r	= name l == name r	-- Ignore 'predicate'. -instance NFData (ShowablePredicate a)	where-	rnf	= rnf . name	--Ignore 'predicate'.+instance Control.DeepSeq.NFData (ShowablePredicate a)	where+	rnf	= Control.DeepSeq.rnf . name	-- Ignore 'predicate'. 
src/RegExDot/Span.hs view
@@ -57,8 +57,8 @@ 	:: ConsumptionBounds.DataLength	-- ^ The offset into the list of input-data to use when a null list of spans is received. 	-> [Span] 	-> Span-join offset []		= empty offset		--The offset can't be deduced from a null list, so use the value provided.-join _ [singleton]	= singleton		--Merely for efficiency.+join offset []		= empty offset		-- The offset can't be deduced from a null list, so use the value provided.+join _ [singleton]	= singleton		-- Merely for efficiency. join _ spanList		= head *** sum $ unzip spanList  
src/RegExDot/Tree.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {- 	Copyright (C) 2010 Dr. Alistair Ward @@ -38,16 +37,11 @@ ) where  import qualified	Control.Arrow+import qualified	Control.DeepSeq import qualified	Data.Foldable import qualified	Data.List import qualified	Data.Monoid -#ifdef HAVE_DEEPSEQ-import			Control.DeepSeq(NFData, rnf)-#else-import			Control.Parallel.Strategies(NFData, rnf)-#endif- -- | A general purpose tree-type structure. data Tree a	= 	Leaf a			-- ^ The payload.@@ -65,16 +59,16 @@ 	readsPrec _ node@('[' : _)	= Control.Arrow.first Node `map` readList node {-singleton-} 	readsPrec _ leaf		= Control.Arrow.first Leaf `map` reads leaf {-singleton-} -instance NFData a => NFData (Tree a)	where-	rnf (Leaf a)	= rnf a-	rnf (Node l)	= rnf l+instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Tree a)	where+	rnf (Leaf a)	= Control.DeepSeq.rnf a+	rnf (Node l)	= Control.DeepSeq.rnf l  instance Functor Tree	where 	fmap f (Leaf a)		= Leaf $ f a 	fmap f (Node treeLists)	= Node $ map (fmap {-recurse-} f `map`) treeLists  instance Data.Foldable.Foldable Tree where-	foldMap f (Leaf a)		= f a	--CAVEAT: 'f' should be Associative, as required by a Monoid.+	foldMap f (Leaf a)		= f a	-- CAVEAT: 'f' should be Associative, as required by a Monoid. 	foldMap f (Node treeLists)	= Data.List.foldl' (Data.List.foldl' (\monoid -> (monoid `Data.Monoid.mappend`) . Data.Foldable.foldMap f)) Data.Monoid.mempty treeLists  -- | Deconstruct the specified 'Node'; i.e. lop the apex from the 'Tree', leaving a flat top.