Commit bd6d5c8e authored by Duncan Coutts's avatar Duncan Coutts Committed by Edward Z. Yang
Browse files

Add ordNubBy and use it in one place in the solver

parent 1440ffd5
......@@ -3,6 +3,7 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE BangPatterns #-}
-----------------------------------------------------------------------------
-- |
......@@ -144,6 +145,7 @@ module Distribution.Simple.Utils (
listUnion,
listUnionRight,
ordNub,
ordNubBy,
ordNubRight,
safeTail,
unintersperse,
......
......@@ -3,6 +3,7 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE BangPatterns #-}
-----------------------------------------------------------------------------
-- |
......@@ -51,6 +52,7 @@ module Distribution.Utils.Generic (
listUnion,
listUnionRight,
ordNub,
ordNubBy,
ordNubRight,
safeTail,
unintersperse,
......@@ -305,15 +307,24 @@ takeWhileEndLE p = fst . foldr go ([], False)
| not done && p x = (x:rest, False)
| otherwise = (rest, True)
-- | Like "Data.List.nub", but has @O(n log n)@ complexity instead of
-- | Like 'Data.List.nub', but has @O(n log n)@ complexity instead of
-- @O(n^2)@. Code for 'ordNub' and 'listUnion' taken from Niklas Hambüchen's
-- <http://github.com/nh2/haskell-ordnub ordnub> package.
ordNub :: (Ord a) => [a] -> [a]
ordNub l = go Set.empty l
ordNub :: Ord a => [a] -> [a]
ordNub = ordNubBy id
-- | Like 'ordNub' and 'Data.List.nubBy'. Selects a key for each element and
-- takes the nub based on that key.
ordNubBy :: Ord b => (a -> b) -> [a] -> [a]
ordNubBy f l = go Set.empty l
where
go _ [] = []
go s (x:xs) = if x `Set.member` s then go s xs
else x : go (Set.insert x s) xs
go !_ [] = []
go !s (x:xs)
| y `Set.member` s = go s xs
| otherwise = let !s' = Set.insert y s
in x : go s' xs
where
y = f x
-- | Like "Data.List.union", but has @O(n log n)@ complexity instead of
-- @O(n^2)@.
......
......@@ -9,10 +9,6 @@ module Distribution.Solver.Modular
-- and finally, we have to convert back the resulting install
-- plan.
import Data.Function
( on )
import Data.List
( nubBy )
import Data.Map as M
( fromListWith )
import Distribution.Compat.Graph
......@@ -34,6 +30,9 @@ import Distribution.Solver.Types.PackageConstraint
import Distribution.Solver.Types.DependencyResolver
import Distribution.System
( Platform(..) )
import Distribution.Simple.Utils
( ordNubBy )
-- | Ties the two worlds together: classic cabal-install vs. the modular
-- solver. Performs the necessary translations before and after.
......@@ -53,8 +52,7 @@ modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns
-- Results have to be converted into an install plan. 'convCP' removes
-- package qualifiers, which means that linked packages become duplicates
-- and can be removed.
-- TODO: Use ordNubBy instead of nubBy.
postprocess a rdm = nubBy ((==) `on` nodeKey) $
postprocess a rdm = ordNubBy nodeKey $
map (convCP iidx sidx) (toCPs a rdm)
-- Helper function to extract the PN from a constraint.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment