diff --git a/.hlint.yaml b/.hlint.yaml index 0ec44ffcfd3..15acf555c89 100644 --- a/.hlint.yaml +++ b/.hlint.yaml @@ -37,6 +37,10 @@ - ignore: {name: "Use fmap", within: [Distribution.Client.HttpUtils, Distribution.Simple.SrcDist]} - ignore: {name: "Use fold", within: [Test.Laws]} +# For lists in these rules we use single letter variables like x rather than xs, +# because "hlint considers only single-letter identifiers as rules' variables. +# Anything longer will match literally". +# SEE: https://github.com/ndmitchell/hlint/issues/1612 - group: name: cabal-suggestions enabled: true @@ -45,6 +49,14 @@ lhs: fromMaybe x (Data.Map.lookup k m) rhs: Map.findWithDefault x k m name: Use findWithDefault + - hint: + lhs: nub x + rhs: ordNub x + name: Use ordNub + note: | + The growth rate of nub is O(n^2) and for ordNub it is O(n log n). May require adding import of either; + - Distribution.Utils.Generic from Cabal-syntax, or + - Distribution.Simple.Utils from Cabal. - arguments: - --ignore-glob=Cabal-syntax/src/Distribution/Fields/Lexer.hs diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index cdafe8f0d7c..0b3721ec86d 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -88,6 +88,7 @@ import qualified Data.ByteString.Char8 as BS8 import qualified Distribution.Compat.CharParsing as P import qualified Distribution.SPDX as SPDX import qualified Distribution.Types.Lens as L +import Distribution.Utils.Generic (ordNub) ------------------------------------------------------------------------------- -- PackageDescription @@ -915,7 +916,7 @@ _syntaxFieldNames = sequence_ [ BS8.putStrLn $ " \\ " <> n | n <- - nub $ + ordNub $ sort $ mconcat [ fieldGrammarKnownFieldList packageDescriptionFieldGrammar @@ -941,7 +942,7 @@ _syntaxExtensions = ] where es = - nub $ + ordNub $ sort [ prettyShow e | e <- [minBound .. maxBound] diff --git a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs index e68fcbc5c22..4c738000b98 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildInfo.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildInfo.hs @@ -28,6 +28,7 @@ import Distribution.Utils.Path import Distribution.Compiler import Distribution.ModuleName +import Distribution.Utils.Generic (ordNub) import Language.Haskell.Extension -- Consider refactoring into executable and library versions. @@ -260,7 +261,7 @@ instance Semigroup BuildInfo where } where combine field = field a `mappend` field b - combineNub field = nub (combine field) + combineNub field = ordNub (combine field) combineMby field = field b `mplus` field a emptyBuildInfo :: BuildInfo diff --git a/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs b/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs index 662a0684cda..e56588f5907 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/PackageDescription/Check.hs @@ -7,6 +7,7 @@ import Distribution.Compat.Prelude import Prelude () import Distribution.PackageDescription.Check +import Distribution.Simple.Utils (ordNub) import Test.Tasty import Test.Tasty.HUnit @@ -26,7 +27,7 @@ tests = allExplanationIdStrings = map ppCheckExplanationId [minBound..maxBound] uniqueNames :: Bool - uniqueNames = length allExplanationIdStrings == length (nub allExplanationIdStrings) + uniqueNames = length allExplanationIdStrings == length (ordNub allExplanationIdStrings) longerThan :: [CheckExplanationIDString] longerThan = filter ((>25). length) allExplanationIdStrings diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/NubList.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/NubList.hs index 28af23f0b89..33aacf4942b 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/NubList.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/NubList.hs @@ -8,6 +8,7 @@ import Prelude () import Distribution.Compat.Prelude.Internal import Distribution.Utils.NubList +import Distribution.Simple.Utils (ordNub) import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck @@ -46,25 +47,25 @@ prop_Ordering :: [Int] -> Property prop_Ordering xs = mempty <> toNubList xs' === toNubList xs' <> mempty where - xs' = nub xs + xs' = ordNub xs prop_DeDupe :: [Int] -> Property prop_DeDupe xs = fromNubList (toNubList (xs' ++ xs)) === xs' -- Note, we append primeless xs where - xs' = nub xs + xs' = ordNub xs prop_DeDupeR :: [Int] -> Property prop_DeDupeR xs = fromNubListR (toNubListR (xs ++ xs')) === xs' -- Note, we prepend primeless xs where - xs' = nub xs + xs' = ordNub xs prop_Nub :: [Int] -> Property prop_Nub xs = rhs === lhs where rhs = fromNubList (toNubList xs) - lhs = nub xs + lhs = ordNub xs prop_Identity :: [Int] -> Bool prop_Identity xs = diff --git a/Cabal/src/Distribution/PackageDescription/Check/Common.hs b/Cabal/src/Distribution/PackageDescription/Check/Common.hs index 0052e25ea79..e50be78206d 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Common.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Common.hs @@ -26,6 +26,7 @@ import Distribution.Compat.NonEmptySet (toNonEmpty) import Distribution.Package import Distribution.PackageDescription import Distribution.PackageDescription.Check.Monad +import Distribution.Simple.Utils (ordNub) import Distribution.Utils.Generic (isAscii) import Distribution.Version @@ -80,7 +81,7 @@ partitionDeps ads ns ds = do -- shared targets that match fads = filter (flip elem dqs . fst) ads -- the names of such targets - inName = nub $ map fst fads :: [UnqualComponentName] + inName = ordNub $ map fst fads :: [UnqualComponentName] -- the dependencies of such targets inDep = concatMap snd fads :: [Dependency] diff --git a/Cabal/src/Distribution/PackageDescription/Check/Target.hs b/Cabal/src/Distribution/PackageDescription/Check/Target.hs index bf6bd80dd01..5e05b6fb5c6 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Target.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Target.hs @@ -559,8 +559,8 @@ checkBuildInfoFeatures bi sv = do checkBuildInfoExtensions :: Monad m => BuildInfo -> CheckM m () checkBuildInfoExtensions bi = do let exts = allExtensions bi - extCabal1_2 = nub $ filter (`elem` compatExtensionsExtra) exts - extCabal1_4 = nub $ filter (`notElem` compatExtensions) exts + extCabal1_2 = ordNub $ filter (`elem` compatExtensionsExtra) exts + extCabal1_4 = ordNub $ filter (`notElem` compatExtensions) exts -- As of Cabal-1.4 we can add new extensions without worrying -- about breaking old versions of cabal. checkSpecVer diff --git a/Cabal/src/Distribution/Simple.hs b/Cabal/src/Distribution/Simple.hs index 9877e861ea5..d6f91c24402 100644 --- a/Cabal/src/Distribution/Simple.hs +++ b/Cabal/src/Distribution/Simple.hs @@ -824,8 +824,8 @@ sanityCheckHookedBuildInfo verbosity pkg_descr (_, hookExes) | exe1 : _ <- nonExistent = dieWithException verbosity $ SanityCheckHookedBuildInfo exe1 where - pkgExeNames = nub (map exeName (executables pkg_descr)) - hookExeNames = nub (map fst hookExes) + pkgExeNames = ordNub (map exeName (executables pkg_descr)) + hookExeNames = ordNub (map fst hookExes) nonExistent = hookExeNames \\ pkgExeNames sanityCheckHookedBuildInfo _ _ _ = return () diff --git a/Cabal/src/Distribution/Simple/BuildTarget.hs b/Cabal/src/Distribution/Simple/BuildTarget.hs index bc72fc2e3cf..0433c583d1d 100644 --- a/Cabal/src/Distribution/Simple/BuildTarget.hs +++ b/Cabal/src/Distribution/Simple/BuildTarget.hs @@ -130,7 +130,7 @@ data BuildTarget BuildTargetModule ComponentName ModuleName | -- | A specific file within a specific component. BuildTargetFile ComponentName FilePath - deriving (Eq, Show, Generic) + deriving (Eq, Ord, Show, Generic) instance Binary BuildTarget @@ -853,7 +853,7 @@ type Confidence = Int data MatchError = MatchErrorExpected String String | MatchErrorNoSuch String String - deriving (Show, Eq) + deriving (Show, Eq, Ord) instance Alternative Match where empty = mzero @@ -943,13 +943,13 @@ increaseConfidence = ExactMatch 1 [()] increaseConfidenceFor :: Match a -> Match a increaseConfidenceFor m = m >>= \r -> increaseConfidence >> return r -nubMatches :: Eq a => Match a -> Match a +nubMatches :: Ord a => Match a -> Match a nubMatches (NoMatch d msgs) = NoMatch d msgs -nubMatches (ExactMatch d xs) = ExactMatch d (nub xs) -nubMatches (InexactMatch d xs) = InexactMatch d (nub xs) +nubMatches (ExactMatch d xs) = ExactMatch d (ordNub xs) +nubMatches (InexactMatch d xs) = InexactMatch d (ordNub xs) nubMatchErrors :: Match a -> Match a -nubMatchErrors (NoMatch d msgs) = NoMatch d (nub msgs) +nubMatchErrors (NoMatch d msgs) = NoMatch d (ordNub msgs) nubMatchErrors (ExactMatch d xs) = ExactMatch d xs nubMatchErrors (InexactMatch d xs) = InexactMatch d xs @@ -970,14 +970,14 @@ tryEach = exactMatches -- | Given a matcher and a key to look up, use the matcher to find all the -- possible matches. There may be 'None', a single 'Unambiguous' match or -- you may have an 'Ambiguous' match with several possibilities. -findMatch :: Eq b => Match b -> MaybeAmbiguous b +findMatch :: Ord b => Match b -> MaybeAmbiguous b findMatch match = case match of - NoMatch _ msgs -> None (nub msgs) + NoMatch _ msgs -> None (ordNub msgs) ExactMatch _ xs -> checkAmbiguous xs InexactMatch _ xs -> checkAmbiguous xs where - checkAmbiguous xs = case nub xs of + checkAmbiguous xs = case ordNub xs of [x] -> Unambiguous x xs' -> Ambiguous xs' diff --git a/Cabal/src/Distribution/Simple/Configure.hs b/Cabal/src/Distribution/Simple/Configure.hs index df1acb72658..69b9a80e16f 100644 --- a/Cabal/src/Distribution/Simple/Configure.hs +++ b/Cabal/src/Distribution/Simple/Configure.hs @@ -1369,14 +1369,14 @@ finalCheckPackage -- Check languages and extensions -- TODO: Move this into a helper function. let langlist = - nub $ + ordNub $ mapMaybe defaultLanguage (enabledBuildInfos pkg_descr enabled) let langs = unsupportedLanguages comp langlist unless (null langs) $ dieWithException verbosity $ UnsupportedLanguages (packageId pkg_descr) (compilerId comp) (map prettyShow langs) let extlist = - nub $ + ordNub $ concatMap allExtensions (enabledBuildInfos pkg_descr enabled) @@ -2607,7 +2607,7 @@ configurePkgconfigPackages verbosity pkg_descr progdb enabled pkgconfigBuildInfo :: [PkgconfigDependency] -> IO BuildInfo pkgconfigBuildInfo [] = return mempty pkgconfigBuildInfo pkgdeps = do - let pkgs = nub [prettyShow pkg | PkgconfigDependency pkg _ <- pkgdeps] + let pkgs = ordNub [prettyShow pkg | PkgconfigDependency pkg _ <- pkgdeps] ccflags <- pkgconfig ("--cflags" : pkgs) ldflags <- pkgconfig ("--libs" : pkgs) ldflags_static <- pkgconfig ("--libs" : "--static" : pkgs) diff --git a/Cabal/src/Distribution/Simple/Register.hs b/Cabal/src/Distribution/Simple/Register.hs index 3e603a14d6a..4fb4126adae 100644 --- a/Cabal/src/Distribution/Simple/Register.hs +++ b/Cabal/src/Distribution/Simple/Register.hs @@ -167,7 +167,7 @@ generateOne verbHandles pkg lib lbi clbi regFlags = -- registering into a totally different db stack can -- fail if dependencies cannot be satisfied. packageDbs = - nub $ + ordNub $ withPackageDB lbi ++ maybeToList (flagToMaybe (regPackageDB regFlags)) distPref = fromFlag $ setupDistPref common @@ -228,7 +228,7 @@ registerAll verbHandles pkg lbi regFlags ipis = -- registering into a totally different db stack can -- fail if dependencies cannot be satisfied. packageDbs = - nub $ + ordNub $ withPackageDB lbi ++ maybeToList (flagToMaybe (regPackageDB regFlags)) common = registerCommonFlags regFlags diff --git a/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs b/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs index 3d767f6fdb8..d7fdf2311f3 100644 --- a/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs +++ b/Cabal/src/Distribution/Simple/SetupHooks/Internal.hs @@ -892,7 +892,7 @@ executeRulesUserOrSystem scope runDepsCmdData runCmdData verbosity lbi tgtInfo a let (ruleGraph, ruleFromVertex, vertexFromRuleId) = Graph.graphFromEdges - [ (rule, rId, nub $ mapMaybe directRuleDependencyMaybe allDeps) + [ (rule, rId, ordNub $ mapMaybe directRuleDependencyMaybe allDeps) | (rId, rule) <- Map.toList allRules , let dynDeps = maybe [] fst (Map.lookup rId dynDepsEdges) allDeps = staticDependencies rule ++ dynDeps diff --git a/Cabal/src/Distribution/Simple/Test.hs b/Cabal/src/Distribution/Simple/Test.hs index fba96b9352f..99f398f3130 100644 --- a/Cabal/src/Distribution/Simple/Test.hs +++ b/Cabal/src/Distribution/Simple/Test.hs @@ -159,7 +159,7 @@ test args verbHandles pkg_descr lbi0 flags = do -- Now, we get the path to the HPC artifacts and exposed modules of each -- library by querying the package database keyed by unit-id: let coverageFor = - nub $ + ordNub $ fromFlagOrDefault [] (configCoverageFor (configFlags lbi)) <> extraCoverageFor lbi ipkginfos <- getInstalledPackagesById verbosity lbi MissingCoveredInstalledLibrary coverageFor diff --git a/Cabal/src/Distribution/Simple/UHC.hs b/Cabal/src/Distribution/Simple/UHC.hs index 8d264d521c2..2a9261a40b0 100644 --- a/Cabal/src/Distribution/Simple/UHC.hs +++ b/Cabal/src/Distribution/Simple/UHC.hs @@ -122,7 +122,7 @@ getInstalledPackages verbosity comp mbWorkDir packagedbs progdb = do let compilerid = compilerId comp systemPkgDir <- getGlobalPackageDir verbosity progdb userPkgDir <- getUserPackageDir - let pkgDirs = nub (concatMap (packageDbPaths userPkgDir systemPkgDir mbWorkDir) packagedbs) + let pkgDirs = ordNub (concatMap (packageDbPaths userPkgDir systemPkgDir mbWorkDir) packagedbs) -- putStrLn $ "pkgdirs: " ++ show pkgDirs pkgs <- map addBuiltinVersions . concat @@ -289,7 +289,7 @@ constructUHCCmdLine user system lbi bi clbi odir verbosity = ++ ["--package=" ++ prettyShow (mungedName pkgid) | (_, pkgid) <- componentPackageDeps clbi] -- search paths ++ ["-i" ++ u odir] - ++ ["-i" ++ u l | l <- nub (hsSourceDirs bi)] + ++ ["-i" ++ u l | l <- ordNub (hsSourceDirs bi)] ++ ["-i" ++ u (autogenComponentModulesDir lbi clbi)] ++ ["-i" ++ u (autogenPackageModulesDir lbi)] -- cpp options diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs index c5c379ad1dc..ee745ca9aba 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Assignment.hs @@ -27,6 +27,7 @@ import Distribution.Solver.Modular.Dependency import Distribution.Solver.Modular.Flag import Distribution.Solver.Modular.LabeledGraph import Distribution.Solver.Modular.Package +import Distribution.Simple.Utils (ordNub) -- | A (partial) package assignment. Qualified package names -- are associated with instances. @@ -53,7 +54,7 @@ toCPs (A pa fa sa) rdm = vm :: Vertex -> ((), QPN, [(Component, QPN)]) cvm :: QPN -> Maybe Vertex -- Note that the RevDepMap contains duplicate dependencies. Therefore the nub. - (g, vm, cvm) = graphFromEdges (L.map (\ (x, xs) -> ((), x, nub xs)) + (g, vm, cvm) = graphFromEdges (L.map (\ (x, xs) -> ((), x, ordNub xs)) (M.toList rdm)) tg :: Graph Component tg = transposeG g diff --git a/cabal-install/src/Distribution/Client/CmdSdist.hs b/cabal-install/src/Distribution/Client/CmdSdist.hs index 0fadca710bf..6ac25d527c1 100644 --- a/cabal-install/src/Distribution/Client/CmdSdist.hs +++ b/cabal-install/src/Distribution/Client/CmdSdist.hs @@ -114,6 +114,7 @@ import Distribution.Simple.SrcDist import Distribution.Simple.Utils ( dieWithException , notice + , ordNub , withOutputMarker , wrapText ) @@ -364,7 +365,7 @@ packageToSdist verbosity projectRootDir format outputFile pkg = do gpd = srcpkgDescription pkg files' <- listPackageSourcesWithDie verbosity dieWithException (Just $ makeSymbolicPath dir) (flattenPackageDescription gpd) knownSuffixHandlers - let files = nub $ sort $ map (normalise . getSymbolicPath) files' + let files = ordNub $ sort $ map (normalise . getSymbolicPath) files' let prefix = makeRelative (normalise projectRootDir) dir write $ concat [prefix i ++ [nulSep] | i <- files] TarGzArchive -> do diff --git a/cabal-install/src/Distribution/Client/Dependency.hs b/cabal-install/src/Distribution/Client/Dependency.hs index 1244308b881..d2cadbbb9b0 100644 --- a/cabal-install/src/Distribution/Client/Dependency.hs +++ b/cabal-install/src/Distribution/Client/Dependency.hs @@ -140,6 +140,7 @@ import Distribution.Verbosity ) import Distribution.Version +import Distribution.Simple.Utils (ordNub) import Distribution.Solver.Types.ComponentDeps (ComponentDeps) import qualified Distribution.Solver.Types.ComponentDeps as CD import Distribution.Solver.Types.ConstraintSource @@ -965,7 +966,7 @@ interpretPackagesPreference selected defaultPref prefs = Map.findWithDefault [] pkgname stanzasPrefs stanzasPrefs = Map.fromListWith - (\a b -> nub (a ++ b)) + (\a b -> ordNub (a ++ b)) [ (pkgname, pref) | PackageStanzasPreference pkgname pref <- prefs ] diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index a6cdffe5c58..e62b949df0e 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -39,6 +39,7 @@ import Distribution.Client.Init.FlagExtractors (getCabalVersionNoPrompt) import Distribution.Client.Init.Types import Distribution.Client.Init.Utils import Distribution.FieldGrammar.Newtypes +import Distribution.Simple.Utils (ordNub) import Distribution.Types.PackageName (PackageName) import Distribution.Version import System.FilePath @@ -132,7 +133,7 @@ guessApplicationDirectories flags = do let candidates = [defaultApplicationDir, "app", "src-exe"] in return $ case [y | x <- candidates, y <- pkgDirsContents, x == y] of [] -> [defaultApplicationDir] - x -> map ( pkgDirs) . nub $ x + x -> map ( pkgDirs) (ordNub x) -- | Try to guess the source directories, using a default value as fallback. guessSourceDirectories :: Interactive m => InitFlags -> m [FilePath] diff --git a/cabal-install/src/Distribution/Client/Install.hs b/cabal-install/src/Distribution/Client/Install.hs index 4082259c9f5..4d382966a78 100644 --- a/cabal-install/src/Distribution/Client/Install.hs +++ b/cabal-install/src/Distribution/Client/Install.hs @@ -229,6 +229,7 @@ import Distribution.Utils.Path hiding import Distribution.Simple.Utils ( VerboseException , createDirectoryIfMissingVerbose + , ordNub , writeFileAtomic ) import Distribution.Simple.Utils as Utils @@ -712,7 +713,7 @@ pruneInstallPlan pkgSpecifiers = ++ "required by a dependency of one of the other targets." where pkgids = - nub + ordNub [ depid | SolverInstallPlan.PackageMissingDeps _ depids <- problems , depid <- depids diff --git a/cabal-install/src/Distribution/Client/RebuildMonad.hs b/cabal-install/src/Distribution/Client/RebuildMonad.hs index 4bc349741d2..b8a06f0c36a 100644 --- a/cabal-install/src/Distribution/Client/RebuildMonad.hs +++ b/cabal-install/src/Distribution/Client/RebuildMonad.hs @@ -68,7 +68,7 @@ import qualified Distribution.Client.Glob as Glob (matchFileGlob) import Distribution.Client.JobControl import Distribution.Simple.PreProcess.Types (Suffix (..)) -import Distribution.Simple.Utils (debug) +import Distribution.Simple.Utils (debug, ordNub) import Control.Concurrent.MVar (MVar, modifyMVar, newMVar) import Control.Monad @@ -330,8 +330,8 @@ findFileWithExtensionMonitored extensions searchPath baseName = findFirstFileMonitored id [ path baseName <.> ext - | path <- nub searchPath - , Suffix ext <- nub extensions + | path <- ordNub searchPath + , Suffix ext <- ordNub extensions ] -- | Like 'findFirstFile', but in the 'Rebuild' monad. @@ -352,5 +352,5 @@ findFileMonitored searchPath fileName = findFirstFileMonitored id [ path fileName - | path <- nub searchPath + | path <- ordNub searchPath ] diff --git a/cabal-install/src/Distribution/Client/SrcDist.hs b/cabal-install/src/Distribution/Client/SrcDist.hs index 46d826cad1a..f191128ac5a 100644 --- a/cabal-install/src/Distribution/Client/SrcDist.hs +++ b/cabal-install/src/Distribution/Client/SrcDist.hs @@ -20,7 +20,7 @@ import Distribution.Package (Package (packageId)) import Distribution.PackageDescription.Configuration (flattenPackageDescription) import Distribution.Simple.PreProcess (knownSuffixHandlers) import Distribution.Simple.SrcDist (listPackageSourcesWithDie) -import Distribution.Simple.Utils (dieWithException) +import Distribution.Simple.Utils (dieWithException, ordNub) import Distribution.Types.GenericPackageDescription (GenericPackageDescription) import Distribution.Utils.Path ( getSymbolicPath @@ -70,7 +70,7 @@ packageDirToSdist verbosity gpd dir = do absDir <- canonicalizePath dir files' <- listPackageSourcesWithDie verbosity dieWithException (Just $ makeSymbolicPath absDir) (flattenPackageDescription gpd) knownSuffixHandlers let files :: [FilePath] - files = nub $ sort $ map (normalise . getSymbolicPath) files' + files = ordNub $ sort $ map (normalise . getSymbolicPath) files' let entriesM :: StateT (Set.Set FilePath) (WriterT [Tar.Entry] IO) () entriesM = do diff --git a/cabal-install/src/Distribution/Client/Targets.hs b/cabal-install/src/Distribution/Client/Targets.hs index 05fa5d09516..9b4ac704661 100644 --- a/cabal-install/src/Distribution/Client/Targets.hs +++ b/cabal-install/src/Distribution/Client/Targets.hs @@ -82,6 +82,7 @@ import Distribution.PackageDescription import Distribution.Simple.Utils ( dieWithException , lowercase + , ordNub ) import Distribution.Types.Flag ( parsecFlagAssignmentNonEmpty @@ -556,7 +557,7 @@ disambiguatePackageName -> PackageName -> MaybeAmbiguous PackageName disambiguatePackageName (PackageNameEnv pkgNameLookup) name = - case nub (pkgNameLookup name) of + case ordNub (pkgNameLookup name) of [] -> None names -> case find (name ==) names of Just name' -> Unambiguous name' diff --git a/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs index 6cc6042f328..fc7ed916a7c 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/UserConfig.hs @@ -6,7 +6,7 @@ module UnitTests.Distribution.Client.UserConfig import Control.Exception (bracket) import Control.Monad (replicateM_) -import Data.List (nub, sort) +import Data.List (sort) import System.Directory ( doesFileExist , getCurrentDirectory @@ -21,7 +21,7 @@ import Test.Tasty.HUnit import Distribution.Client.Config import Distribution.Client.Setup (GlobalFlags (..), InstallFlags (..)) import Distribution.Simple.Setup (ConfigFlags (..), fromFlag, pattern Flag) -import Distribution.Simple.Utils (removeFileForcibly, withTempDirectory) +import Distribution.Simple.Utils (ordNub, removeFileForcibly, withTempDirectory) import Distribution.Utils.NubList (fromNubList) import Distribution.Verbosity @@ -93,7 +93,7 @@ globalFlags configFile = mempty{globalConfigFile = Flag configFile} listUnique :: Ord a => [a] -> Bool listUnique xs = let sorted = sort xs - in nub sorted == xs + in ordNub sorted == xs bracketTest :: (FilePath -> IO ()) -> Assertion bracketTest = diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs index ab056c820c9..ab35b93b8b3 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/QuickCheck.hs @@ -43,6 +43,7 @@ import Distribution.Solver.Types.Variable import Distribution.Verbosity import Distribution.Version +import Distribution.Simple.Utils (ordNub) import UnitTests.Distribution.Solver.Modular.DSL import UnitTests.Distribution.Solver.Modular.QuickCheck.Utils ( ArbitraryOrd (..) @@ -343,8 +344,8 @@ instance Show SolverTest where instance Arbitrary SolverTest where arbitrary = do db <- arbitrary - let pkgVersions = nub $ map (getName &&& getVersion) (unTestDb db) - pkgs = nub $ map fst pkgVersions + let pkgVersions = ordNub $ map (getName &&& getVersion) (unTestDb db) + pkgs = ordNub $ map fst pkgVersions Positive n <- arbitrary targets <- randomSubset n pkgs constraints <- case pkgVersions of diff --git a/solver-benchmarks/HackageBenchmark.hs b/solver-benchmarks/HackageBenchmark.hs index 37996dbfc63..46e20cb1b05 100644 --- a/solver-benchmarks/HackageBenchmark.hs +++ b/solver-benchmarks/HackageBenchmark.hs @@ -16,7 +16,7 @@ module HackageBenchmark ( import Control.Concurrent.Async (concurrently) import Control.Monad (forM, replicateM, unless, when) import qualified Data.ByteString as BS -import Data.List (nub, unzip4) +import Data.List (unzip4) import Data.Maybe (isJust, catMaybes) import Data.String (fromString) import Data.Function ((&)) @@ -41,6 +41,7 @@ import Text.Printf (printf) import qualified Data.Map.Strict as Map import Distribution.Package (PackageName, mkPackageName, unPackageName) +import Distribution.Utils.Generic (ordNub) data Args = Args { argCabal1 :: FilePath @@ -70,7 +71,7 @@ data CabalResult | PkgNotFound | Timeout | Unknown - deriving (Eq, Show) + deriving (Eq, Ord, Show) hackageBenchmarkMain :: IO () hackageBenchmarkMain = do @@ -185,7 +186,7 @@ hackageBenchmarkMain = do then do putStrLn $ "Obtaining the package list (using " ++ argCabal1 ++ ") ..." list <- readProcess argCabal1 ["list", "--simple-output"] "" - return $ nub [mkPackageName n | n : _ <- words <$> lines list] + return $ ordNub ([mkPackageName n | n : _ <- words <$> lines list]) else do putStrLn "Using given package list ..." return argPackages @@ -348,8 +349,8 @@ combineTrialResults rs | allEqual [r | r <- rs, r /= Timeout] = Timeout | otherwise = Unknown where - allEqual :: Eq a => [a] -> Bool - allEqual xs = length (nub xs) == 1 + allEqual :: Ord a => [a] -> Bool + allEqual xs = length (ordNub xs) == 1 timeEvent :: IO a -> IO (a, NominalDiffTime) timeEvent task = do