module Data.List.Extended (
    module Data.List
    , minimumOn
    , nubOrd
) where



import           Data.List
import qualified Data.Set  as S



minimumOn :: Ord a1 => (a2 -> a1) -> [a2] -> Maybe a2
minimumOn :: forall a1 a2. Ord a1 => (a2 -> a1) -> [a2] -> Maybe a2
minimumOn a2 -> a1
_ [] = Maybe a2
forall a. Maybe a
Nothing
minimumOn a2 -> a1
f [a2]
xs = a2 -> Maybe a2
forall a. a -> Maybe a
Just ((a2 -> a2 -> Ordering) -> [a2] -> a2
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (\a2
a a2
b -> a1 -> a1 -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (a2 -> a1
f a2
a) (a2 -> a1
f a2
b)) [a2]
xs)

-- | 'nub', but based on 'S.Set' for performance reasons.
nubOrd :: Ord a => [a] -> [a]
nubOrd :: forall a. Ord a => [a] -> [a]
nubOrd = Set a -> [a] -> [a]
forall {a}. Ord a => Set a -> [a] -> [a]
go Set a
forall a. Set a
S.empty
  where
    go :: Set a -> [a] -> [a]
go Set a
_ [] = []
    go Set a
seen (a
x:[a]
xs)
        | a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
S.member a
x Set a
seen = Set a -> [a] -> [a]
go Set a
seen [a]
xs
        | Bool
otherwise       = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Set a -> [a] -> [a]
go (a -> Set a -> Set a
forall a. Ord a => a -> Set a -> Set a
S.insert a
x Set a
seen) [a]
xs