{-# 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 (elemIndices, findIndex, intercalate,
isInfixOf, isPrefixOf, isSuffixOf, nub,
tails)
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 a -> a -> Ordering
_ [] [a]
ys = [a]
ys
mergeBy a -> a -> Ordering
_ [a]
xs [] = [a]
xs
mergeBy a -> a -> Ordering
cmp (allx :: [a]
allx@(a
x:[a]
xs)) (ally :: [a]
ally@(a
y:[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 [] [a]
_ = Bool
False
hasAny [a]
_ [] = Bool
False
hasAny [a]
search (a
x:[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 [a] -> Bool
_ [] = []
takeWhileList [a] -> Bool
func list :: [a]
list@(a
x:[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 [a] -> Bool
_ [] = []
dropWhileList [a] -> Bool
func list :: [a]
list@(a
_:[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 [a] -> Bool
_ [] = ([],[])
spanList [a] -> Bool
func list :: [a]
list@(a
x:[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 ([a]
ys,[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 [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 [a]
_ [] = []
split [a]
delim [a]
str =
let ([a]
firstline, [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
[] -> []
[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 [a]
old [a]
new [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 = [a] -> [[a]] -> [a]
forall a. [a] -> [[a]] -> [a]
intercalate
genericJoin :: Show a => String -> [a] -> String
genericJoin :: String -> [a] -> String
genericJoin String
delim [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)
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 [(key, elt)]
l key
key 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 [(key, a)]
l key
key = ((key, a) -> Bool) -> [(key, a)] -> [(key, a)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(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 a
key [(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 [(key, val)]
oldl =
let worker :: (Eq key, Eq val) => [(key, val)] -> [(val, [key])] -> [(val, [key])]
worker :: [(key, val)] -> [(val, [key])] -> [(val, [key])]
worker [] [(val, [key])]
accum = [(val, [key])]
accum
worker ((key
k, val
v):[(key, val)]
xs) [(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
Maybe [key]
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 [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 [(a, b)]
inp =
let worker :: (a, a) -> String
worker (a
key, a
val) = a -> String
forall a. Show a => a -> String
show a
key String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," 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 String
inp =
let worker :: String -> (a, b)
worker String
line =
case ReadS a
forall a. Read a => ReadS a
reads String
line of
[(a
key, String
remainder)] -> case String
remainder of
Char
',':String
valstr -> (a
key, String -> b
forall a. Read a => String -> a
read String
valstr)
String
_ -> String -> (a, b)
forall a. HasCallStack => String -> a
error String
"Data.List.Utils.strToAL: Parse error on value"
[(a, String)]
_ -> String -> (a, b)
forall a. HasCallStack => String -> a
error String
"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 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 a
item [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
(Int
x:[Int]
_) -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
x
alwaysElemRIndex :: Eq a => a -> [a] -> Int
alwaysElemRIndex :: a -> [a] -> Int
alwaysElemRIndex a
item [a]
list =
case a -> [a] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemRIndex a
item [a]
list of
Maybe Int
Nothing -> -Int
1
Just Int
x -> Int
x
seqList :: [a] -> [a]
seqList :: [a] -> [a]
seqList [] = []
seqList list :: [a]
list@(a
_:[a]
xs) = [a] -> [a] -> [a]
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 WholeFunc a b
_ [] = []
wholeMap (WholeFunc [a] -> (WholeFunc a b, [a], [b])
func) [a]
inplist =
let (WholeFunc a b
nextfunc, [a]
nextlist, [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 =
([a] -> (WholeFunc a [a], [a], [[a]])) -> WholeFunc a [a]
forall a b. ([a] -> (WholeFunc a b, [a], [b])) -> WholeFunc a b
WholeFunc (([a] -> (WholeFunc a [a], [a], [[a]])) -> WholeFunc a [a])
-> ([Int] -> [a] -> (WholeFunc a [a], [a], [[a]]))
-> [Int]
-> WholeFunc a [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [a] -> (WholeFunc a [a], [a], [[a]])
forall a a. [Int] -> [a] -> (WholeFunc a [a], [a], [[a]])
fixedWidthFunc
where
fixedWidthFunc :: [Int] -> [a] -> (WholeFunc a [a], [a], [[a]])
fixedWidthFunc [Int]
_ [] = (([Int] -> WholeFunc a [a]
forall a. [Int] -> WholeFunc a [a]
fixedWidth []), [], [])
fixedWidthFunc [] [a]
x = (([Int] -> WholeFunc a [a]
forall a. [Int] -> WholeFunc a [a]
fixedWidth []), [], [[a]
x])
fixedWidthFunc (Int
len:[Int]
lenxs) [a]
input =
([Int] -> WholeFunc a [a]
forall a. [Int] -> WholeFunc a [a]
fixedWidth [Int]
lenxs, [a]
next, [[a]
this])
where ([a]
this, [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 Int
count =
do [a]
g <- State [a] [a]
forall s (m :: * -> *). MonadState s m => m s
get
([a]
x, [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 [a]
substr [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