{-# LANGUAGE Safe #-}
module Data.List.Utils(
merge, mergeBy,
startswith, endswith, contains, hasAny,
addToAL, delFromAL, flipAL, keysAL, valuesAL,
hasKeyAL,
strFromAL,
strToAL,
split, join, replace, genericJoin, takeWhileList,
dropWhileList, spanList, breakList,
WholeFunc(..), wholeMap, fixedWidth,
grab,
countElem, elemRIndex, alwaysElemRIndex, seqList,
subIndex, uniq
) where
import Control.Monad.State (State, get, put)
import Data.List (concat, elemIndex, elemIndices,
elemIndices, find, findIndex, intersperse,
isInfixOf, isPrefixOf, isSuffixOf, nub,
tails)
import Data.Maybe (isJust)
merge :: (Ord a) => [a] -> [a] -> [a]
merge :: [a] -> [a] -> [a]
merge = (a -> a -> Ordering) -> [a] -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy (a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare)
mergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy cmp :: a -> a -> Ordering
cmp [] ys :: [a]
ys = [a]
ys
mergeBy cmp :: a -> a -> Ordering
cmp xs :: [a]
xs [] = [a]
xs
mergeBy cmp :: a -> a -> Ordering
cmp (allx :: [a]
allx@(x :: a
x:xs :: [a]
xs)) (ally :: [a]
ally@(y :: a
y:ys :: [a]
ys))
| (a
x a -> a -> Ordering
`cmp` a
y) Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
<= Ordering
EQ = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a -> Ordering) -> [a] -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy a -> a -> Ordering
cmp [a]
xs [a]
ally
| Bool
otherwise = a
y a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a -> Ordering) -> [a] -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a] -> [a]
mergeBy a -> a -> Ordering
cmp [a]
allx [a]
ys
startswith :: Eq a => [a] -> [a] -> Bool
startswith :: [a] -> [a] -> Bool
startswith = [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf
endswith :: Eq a => [a] -> [a] -> Bool
endswith :: [a] -> [a] -> Bool
endswith = [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isSuffixOf
hasAny :: Eq a => [a]
-> [a]
-> Bool
hasAny :: [a] -> [a] -> Bool
hasAny [] _ = Bool
False
hasAny _ [] = Bool
False
hasAny search :: [a]
search (x :: a
x:xs :: [a]
xs) = if a
x a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a]
search then Bool
True else [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
hasAny [a]
search [a]
xs
takeWhileList :: ([a] -> Bool) -> [a] -> [a]
takeWhileList :: ([a] -> Bool) -> [a] -> [a]
takeWhileList _ [] = []
takeWhileList func :: [a] -> Bool
func list :: [a]
list@(x :: a
x:xs :: [a]
xs) =
if [a] -> Bool
func [a]
list
then a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: ([a] -> Bool) -> [a] -> [a]
forall a. ([a] -> Bool) -> [a] -> [a]
takeWhileList [a] -> Bool
func [a]
xs
else []
dropWhileList :: ([a] -> Bool) -> [a] -> [a]
dropWhileList :: ([a] -> Bool) -> [a] -> [a]
dropWhileList _ [] = []
dropWhileList func :: [a] -> Bool
func list :: [a]
list@(x :: a
x:xs :: [a]
xs) =
if [a] -> Bool
func [a]
list
then ([a] -> Bool) -> [a] -> [a]
forall a. ([a] -> Bool) -> [a] -> [a]
dropWhileList [a] -> Bool
func [a]
xs
else [a]
list
spanList :: ([a] -> Bool) -> [a] -> ([a], [a])
spanList :: ([a] -> Bool) -> [a] -> ([a], [a])
spanList _ [] = ([],[])
spanList func :: [a] -> Bool
func list :: [a]
list@(x :: a
x:xs :: [a]
xs) =
if [a] -> Bool
func [a]
list
then (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ys,[a]
zs)
else ([],[a]
list)
where (ys :: [a]
ys,zs :: [a]
zs) = ([a] -> Bool) -> [a] -> ([a], [a])
forall a. ([a] -> Bool) -> [a] -> ([a], [a])
spanList [a] -> Bool
func [a]
xs
breakList :: ([a] -> Bool) -> [a] -> ([a], [a])
breakList :: ([a] -> Bool) -> [a] -> ([a], [a])
breakList func :: [a] -> Bool
func = ([a] -> Bool) -> [a] -> ([a], [a])
forall a. ([a] -> Bool) -> [a] -> ([a], [a])
spanList (Bool -> Bool
not (Bool -> Bool) -> ([a] -> Bool) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Bool
func)
split :: Eq a => [a] -> [a] -> [[a]]
split :: [a] -> [a] -> [[a]]
split _ [] = []
split delim :: [a]
delim str :: [a]
str =
let (firstline :: [a]
firstline, remainder :: [a]
remainder) = ([a] -> Bool) -> [a] -> ([a], [a])
forall a. ([a] -> Bool) -> [a] -> ([a], [a])
breakList ([a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
startswith [a]
delim) [a]
str
in
[a]
firstline [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: case [a]
remainder of
[] -> []
x :: [a]
x -> if [a]
x [a] -> [a] -> Bool
forall a. Eq a => a -> a -> Bool
== [a]
delim
then [] [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: []
else [a] -> [a] -> [[a]]
forall a. Eq a => [a] -> [a] -> [[a]]
split [a]
delim
(Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
delim) [a]
x)
replace :: Eq a => [a] -> [a] -> [a] -> [a]
replace :: [a] -> [a] -> [a] -> [a]
replace old :: [a]
old new :: [a]
new l :: [a]
l = [a] -> [[a]] -> [a]
forall a. [a] -> [[a]] -> [a]
join [a]
new ([[a]] -> [a]) -> ([a] -> [[a]]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a] -> [[a]]
forall a. Eq a => [a] -> [a] -> [[a]]
split [a]
old ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ [a]
l
join :: [a] -> [[a]] -> [a]
join :: [a] -> [[a]] -> [a]
join delim :: [a]
delim l :: [[a]]
l = [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
intersperse [a]
delim [[a]]
l)
genericJoin :: Show a => String -> [a] -> String
genericJoin :: String -> [a] -> String
genericJoin delim :: String
delim l :: [a]
l = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
join String
delim ((a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map a -> String
forall a. Show a => a -> String
show [a]
l)
{-# DEPRECATED contains "Use Data.List.isInfixOf, will be removed in MissingH 1.1.0" #-}
contains :: Eq a => [a] -> [a] -> Bool
contains :: [a] -> [a] -> Bool
contains = [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isInfixOf
addToAL :: Eq key => [(key, elt)] -> key -> elt -> [(key, elt)]
addToAL :: [(key, elt)] -> key -> elt -> [(key, elt)]
addToAL l :: [(key, elt)]
l key :: key
key value :: elt
value = (key
key, elt
value) (key, elt) -> [(key, elt)] -> [(key, elt)]
forall a. a -> [a] -> [a]
: [(key, elt)] -> key -> [(key, elt)]
forall key a. Eq key => [(key, a)] -> key -> [(key, a)]
delFromAL [(key, elt)]
l key
key
delFromAL :: Eq key => [(key, a)] -> key -> [(key, a)]
delFromAL :: [(key, a)] -> key -> [(key, a)]
delFromAL l :: [(key, a)]
l key :: key
key = ((key, a) -> Bool) -> [(key, a)] -> [(key, a)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\a :: (key, a)
a -> ((key, a) -> key
forall a b. (a, b) -> a
fst (key, a)
a) key -> key -> Bool
forall a. Eq a => a -> a -> Bool
/= key
key) [(key, a)]
l
keysAL :: [(key, a)] -> [key]
keysAL :: [(key, a)] -> [key]
keysAL = ((key, a) -> key) -> [(key, a)] -> [key]
forall a b. (a -> b) -> [a] -> [b]
map (key, a) -> key
forall a b. (a, b) -> a
fst
valuesAL :: [(a, value)] -> [value]
valuesAL :: [(a, value)] -> [value]
valuesAL = ((a, value) -> value) -> [(a, value)] -> [value]
forall a b. (a -> b) -> [a] -> [b]
map (a, value) -> value
forall a b. (a, b) -> b
snd
hasKeyAL :: Eq a => a -> [(a, b)] -> Bool
hasKeyAL :: a -> [(a, b)] -> Bool
hasKeyAL key :: a
key list :: [(a, b)]
list =
a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem a
key ([(a, b)] -> [a]
forall key a. [(key, a)] -> [key]
keysAL [(a, b)]
list)
flipAL :: (Eq key, Eq val) => [(key, val)] -> [(val, [key])]
flipAL :: [(key, val)] -> [(val, [key])]
flipAL oldl :: [(key, val)]
oldl =
let worker :: (Eq key, Eq val) => [(key, val)] -> [(val, [key])] -> [(val, [key])]
worker :: [(key, val)] -> [(val, [key])] -> [(val, [key])]
worker [] accum :: [(val, [key])]
accum = [(val, [key])]
accum
worker ((k :: key
k, v :: val
v):xs :: [(key, val)]
xs) accum :: [(val, [key])]
accum =
case val -> [(val, [key])] -> Maybe [key]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup val
v [(val, [key])]
accum of
Nothing -> [(key, val)] -> [(val, [key])] -> [(val, [key])]
forall key val.
(Eq key, Eq val) =>
[(key, val)] -> [(val, [key])] -> [(val, [key])]
worker [(key, val)]
xs ((val
v, [key
k]) (val, [key]) -> [(val, [key])] -> [(val, [key])]
forall a. a -> [a] -> [a]
: [(val, [key])]
accum)
Just y :: [key]
y -> [(key, val)] -> [(val, [key])] -> [(val, [key])]
forall key val.
(Eq key, Eq val) =>
[(key, val)] -> [(val, [key])] -> [(val, [key])]
worker [(key, val)]
xs ([(val, [key])] -> val -> [key] -> [(val, [key])]
forall key elt.
Eq key =>
[(key, elt)] -> key -> elt -> [(key, elt)]
addToAL [(val, [key])]
accum val
v (key
kkey -> [key] -> [key]
forall a. a -> [a] -> [a]
:[key]
y))
in
[(key, val)] -> [(val, [key])] -> [(val, [key])]
forall key val.
(Eq key, Eq val) =>
[(key, val)] -> [(val, [key])] -> [(val, [key])]
worker [(key, val)]
oldl []
strFromAL :: (Show a, Show b) => [(a, b)] -> String
strFromAL :: [(a, b)] -> String
strFromAL inp :: [(a, b)]
inp =
let worker :: (a, a) -> String
worker (key :: a
key, val :: a
val) = a -> String
forall a. Show a => a -> String
show a
key String -> String -> String
forall a. [a] -> [a] -> [a]
++ "," String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
val
in [String] -> String
unlines ([String] -> String)
-> ([(a, b)] -> [String]) -> [(a, b)] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, b) -> String) -> [(a, b)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (a, b) -> String
forall a a. (Show a, Show a) => (a, a) -> String
worker ([(a, b)] -> String) -> [(a, b)] -> String
forall a b. (a -> b) -> a -> b
$ [(a, b)]
inp
strToAL :: (Read a, Read b) => String -> [(a, b)]
strToAL :: String -> [(a, b)]
strToAL inp :: String
inp =
let worker :: String -> (a, b)
worker line :: String
line =
case ReadS a
forall a. Read a => ReadS a
reads String
line of
[(key :: a
key, remainder :: String
remainder)] -> case String
remainder of
',':valstr :: String
valstr -> (a
key, String -> b
forall a. Read a => String -> a
read String
valstr)
_ -> String -> (a, b)
forall a. HasCallStack => String -> a
error "Data.List.Utils.strToAL: Parse error on value"
_ -> String -> (a, b)
forall a. HasCallStack => String -> a
error "Data.List.Utils.strToAL: Parse error on key"
in (String -> (a, b)) -> [String] -> [(a, b)]
forall a b. (a -> b) -> [a] -> [b]
map String -> (a, b)
forall a b. (Read a, Read b) => String -> (a, b)
worker (String -> [String]
lines String
inp)
countElem :: Eq a => a -> [a] -> Int
countElem :: a -> [a] -> Int
countElem i :: a
i = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> ([a] -> [a]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a
ia -> a -> Bool
forall a. Eq a => a -> a -> Bool
==)
elemRIndex :: Eq a => a -> [a] -> Maybe Int
elemRIndex :: a -> [a] -> Maybe Int
elemRIndex item :: a
item l :: [a]
l =
case [Int] -> [Int]
forall a. [a] -> [a]
reverse ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ a -> [a] -> [Int]
forall a. Eq a => a -> [a] -> [Int]
elemIndices a
item [a]
l of
[] -> Maybe Int
forall a. Maybe a
Nothing
(x :: Int
x:_) -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
x
alwaysElemRIndex :: Eq a => a -> [a] -> Int
alwaysElemRIndex :: a -> [a] -> Int
alwaysElemRIndex item :: a
item list :: [a]
list =
case a -> [a] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemRIndex a
item [a]
list of
Nothing -> -1
Just x :: Int
x -> Int
x
seqList :: [a] -> [a]
seqList :: [a] -> [a]
seqList [] = []
seqList list :: [a]
list@(x :: a
x:xs :: [a]
xs) = [a] -> [a] -> [a]
forall a b. a -> b -> b
seq ([a] -> [a]
forall a. [a] -> [a]
seqList [a]
xs) [a]
list
newtype WholeFunc a b = WholeFunc ([a] -> (WholeFunc a b, [a], [b]))
wholeMap :: WholeFunc a b -> [a] -> [b]
wholeMap :: WholeFunc a b -> [a] -> [b]
wholeMap _ [] = []
wholeMap (WholeFunc func :: [a] -> (WholeFunc a b, [a], [b])
func) inplist :: [a]
inplist =
let (nextfunc :: WholeFunc a b
nextfunc, nextlist :: [a]
nextlist, output :: [b]
output) = [a] -> (WholeFunc a b, [a], [b])
func [a]
inplist
in
[b]
output [b] -> [b] -> [b]
forall a. [a] -> [a] -> [a]
++ WholeFunc a b -> [a] -> [b]
forall a b. WholeFunc a b -> [a] -> [b]
wholeMap WholeFunc a b
nextfunc [a]
nextlist
fixedWidth :: [Int] -> WholeFunc a [a]
fixedWidth :: [Int] -> WholeFunc a [a]
fixedWidth len :: [Int]
len =
([a] -> (WholeFunc a [a], [a], [[a]])) -> WholeFunc a [a]
forall a b. ([a] -> (WholeFunc a b, [a], [b])) -> WholeFunc a b
WholeFunc ([Int] -> [a] -> (WholeFunc a [a], [a], [[a]])
forall a a. [Int] -> [a] -> (WholeFunc a [a], [a], [[a]])
fixedWidthFunc [Int]
len)
where
fixedWidthFunc :: [Int] -> [a] -> (WholeFunc a [a], [a], [[a]])
fixedWidthFunc _ [] = (([Int] -> WholeFunc a [a]
forall a. [Int] -> WholeFunc a [a]
fixedWidth []), [], [])
fixedWidthFunc [] x :: [a]
x = (([Int] -> WholeFunc a [a]
forall a. [Int] -> WholeFunc a [a]
fixedWidth []), [], [[a]
x])
fixedWidthFunc (len :: Int
len:lenxs :: [Int]
lenxs) input :: [a]
input =
([Int] -> WholeFunc a [a]
forall a. [Int] -> WholeFunc a [a]
fixedWidth [Int]
lenxs, [a]
next, [[a]
this])
where (this :: [a]
this, next :: [a]
next) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
len [a]
input
grab :: Int -> State [a] [a]
grab :: Int -> State [a] [a]
grab count :: Int
count =
do [a]
g <- State [a] [a]
forall s (m :: * -> *). MonadState s m => m s
get
(x :: [a]
x, g' :: [a]
g') <- ([a], [a]) -> StateT [a] Identity ([a], [a])
forall (m :: * -> *) a. Monad m => a -> m a
return (([a], [a]) -> StateT [a] Identity ([a], [a]))
-> ([a], [a]) -> StateT [a] Identity ([a], [a])
forall a b. (a -> b) -> a -> b
$ Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
count [a]
g
[a] -> StateT [a] Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put [a]
g'
[a] -> State [a] [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [a]
x
subIndex :: Eq a => [a] -> [a] -> Maybe Int
subIndex :: [a] -> [a] -> Maybe Int
subIndex substr :: [a]
substr str :: [a]
str = ([a] -> Bool) -> [[a]] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex ([a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf [a]
substr) ([a] -> [[a]]
forall a. [a] -> [[a]]
tails [a]
str)
uniq :: Eq a => [a] -> [a]
uniq :: [a] -> [a]
uniq = [a] -> [a]
forall a. Eq a => [a] -> [a]
nub