{-# LANGUAGE CPP #-}
module Data.Express.Utils.List
( nubSort
, nubSortBy
, isPermutationOf
, isSubsetOf
, isNub
, lookupId
, (+++)
, module Data.List
#if __GLASGOW_HASKELL__ < 710
, isSubsequenceOf
#endif
)
where
import Data.Function (on)
import Data.List
import Data.Maybe (fromMaybe)
nubSort :: Ord a => [a] -> [a]
nubSort = nnub . sort
where
nnub [] = []
nnub [x] = [x]
nnub (x:xs) = x : nnub (dropWhile (==x) xs)
nubSortBy :: (a -> a -> Ordering) -> [a] -> [a]
nubSortBy cmp = nnub . sortBy cmp
where
x -==- y = x `cmp` y == EQ
nnub [] = []
nnub [x] = [x]
nnub (x:xs) = x : nnub (dropWhile (-==-x) xs)
isSubsetOf :: Ord a => [a] -> [a] -> Bool
xs `isSubsetOf` ys = nubSort xs `isSubsequenceOf` nubSort ys
#if __GLASGOW_HASKELL__ < 710
isSubsequenceOf :: Eq a => [a] -> [a] -> Bool
isSubsequenceOf [] _ = True
isSubsequenceOf (_:_) [] = False
isSubsequenceOf (x:xs) (y:ys) | x == y = xs `isSubsequenceOf` ys
| otherwise = (x:xs) `isSubsequenceOf` ys
#endif
isPermutationOf :: Ord a => [a] -> [a] -> Bool
isPermutationOf = (==) `on` sort
isNub :: Ord a => [a] -> Bool
isNub xs = length (nubSort xs) == length xs
lookupId :: Eq a => a -> [(a,a)] -> a
lookupId x = fromMaybe x . lookup x
(+++) :: Ord a => [a] -> [a] -> [a]
(+++) = nubMerge
infixr 5 +++
nubMergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
nubMergeBy cmp (x:xs) (y:ys) = case x `cmp` y of
LT -> x:nubMergeBy cmp xs (y:ys)
GT -> y:nubMergeBy cmp (x:xs) ys
EQ -> x:nubMergeBy cmp xs ys
nubMergeBy _ xs ys = xs ++ ys
nubMerge :: Ord a => [a] -> [a] -> [a]
nubMerge = nubMergeBy compare