{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns #-}
module Haskus.Utils.List
( at
, unsafeAt
, checkLength
, (++)
, replicate
, drop
, length
, take
, chunksOf
, pick1
, enumList
, zipLeftWith
, zipRightWith
, L.partition
, L.nub
, L.sort
, L.intersperse
, L.foldl'
, L.head
, L.tail
, L.zipWith
, L.repeat
, nubOn
, L.nubBy
, L.sortOn
, L.sortBy
, groupOn
, L.groupBy
, L.transpose
, (L.\\)
, L.intersect
, L.find
, L.zip3
, L.zip4
, L.zip5
, L.zip6
, L.zip7
, L.stripPrefix
, L.isPrefixOf
, L.deleteBy
, L.isSuffixOf
, L.elem
, L.notElem
, splitAt
, split
, splitOn
, breakOn
)
where
import Prelude hiding (replicate, length, drop, take,splitAt)
import Data.Bifunctor
import Data.Function (on)
import qualified Data.List as L
at :: [a] -> Word -> Maybe a
{-# INLINABLE at #-}
at :: [a] -> Word -> Maybe a
at = [a] -> Word -> Maybe a
forall t a. (Eq t, Num t) => [a] -> t -> Maybe a
go
where
go :: [a] -> t -> Maybe a
go [] t
_ = Maybe a
forall a. Maybe a
Nothing
go (a
x:[a]
_xs) t
0 = a -> Maybe a
forall a. a -> Maybe a
Just a
x
go (a
_x:[a]
xs) !t
n = [a] -> t -> Maybe a
go [a]
xs (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1)
unsafeAt :: [a] -> Word -> a
{-# INLINABLE unsafeAt #-}
unsafeAt :: [a] -> Word -> a
unsafeAt [a]
vs Word
k = [a] -> Word -> a
forall t p. (Eq t, Num t) => [p] -> t -> p
go [a]
vs Word
k
where
go :: [p] -> t -> p
go [] t
_ = [Char] -> p
forall a. HasCallStack => [Char] -> a
error ([Char]
"Unsafe list index too large: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Word -> [Char]
forall a. Show a => a -> [Char]
show Word
k)
go (p
x:[p]
_xs) t
0 = p
x
go (p
_x:[p]
xs) !t
n = [p] -> t -> p
go [p]
xs (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1)
checkLength :: Word -> [a] -> Bool
checkLength :: Word -> [a] -> Bool
checkLength Word
0 [] = Bool
True
checkLength Word
0 [a]
_ = Bool
False
checkLength Word
_ [] = Bool
False
checkLength Word
i (a
_:[a]
xs) = Word -> [a] -> Bool
forall a. Word -> [a] -> Bool
checkLength (Word
iWord -> Word -> Word
forall a. Num a => a -> a -> a
-Word
1) [a]
xs
replicate :: Word -> a -> [a]
replicate :: Word -> a -> [a]
replicate Word
n a
a = Int -> a -> [a]
forall a. Int -> a -> [a]
L.replicate (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n) a
a
take :: Word -> [a] -> [a]
take :: Word -> [a] -> [a]
take Word
n = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
L.take (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n)
length :: Foldable t => t a -> Word
length :: t a -> Word
length = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> (t a -> Int) -> t a -> Word
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
L.length
drop :: Word -> [a] -> [a]
drop :: Word -> [a] -> [a]
drop Word
n = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
L.drop (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
n)
repeatedly :: ([a] -> (b, [a])) -> [a] -> [b]
repeatedly :: ([a] -> (b, [a])) -> [a] -> [b]
repeatedly [a] -> (b, [a])
_ [] = []
repeatedly [a] -> (b, [a])
f [a]
as = b
b b -> [b] -> [b]
forall a. a -> [a] -> [a]
: ([a] -> (b, [a])) -> [a] -> [b]
forall a b. ([a] -> (b, [a])) -> [a] -> [b]
repeatedly [a] -> (b, [a])
f [a]
as'
where (b
b, [a]
as') = [a] -> (b, [a])
f [a]
as
chunksOf :: Word -> [a] -> [[a]]
chunksOf :: Word -> [a] -> [[a]]
chunksOf Word
i [a]
xs = ([a] -> ([a], [a])) -> [a] -> [[a]]
forall a b. ([a] -> (b, [a])) -> [a] -> [b]
repeatedly (Word -> [a] -> ([a], [a])
forall n a. Integral n => n -> [a] -> ([a], [a])
splitAt Word
i) [a]
xs
pick1 :: [a] -> [(a,[a])]
pick1 :: [a] -> [(a, [a])]
pick1 = [a] -> [a] -> [(a, [a])]
forall a. [a] -> [a] -> [(a, [a])]
go []
where
go :: [a] -> [a] -> [(a, [a])]
go [a]
_ [] = []
go [a]
ys (a
x:[a]
xs) = (a
x,[a] -> [a]
forall a. [a] -> [a]
reverse [a]
ys[a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++[a]
xs) (a, [a]) -> [(a, [a])] -> [(a, [a])]
forall a. a -> [a] -> [a]
: [a] -> [a] -> [(a, [a])]
go (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ys) [a]
xs
enumList :: forall a. (Bounded a,Enum a) => [a]
enumList :: [a]
enumList = a -> [a]
forall a. Enum a => a -> [a]
enumFrom a
forall a. Bounded a => a
minBound
zipLeftWith :: (a -> b) -> [a] -> [(b,a)]
zipLeftWith :: (a -> b) -> [a] -> [(b, a)]
zipLeftWith a -> b
f [a]
xs = (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f [a]
xs [b] -> [a] -> [(b, a)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [a]
xs
zipRightWith :: (a -> b) -> [a] -> [(a,b)]
zipRightWith :: (a -> b) -> [a] -> [(a, b)]
zipRightWith a -> b
f [a]
xs = [a]
xs [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f [a]
xs
nubOn :: Eq b => (a -> b) -> [a] -> [a]
nubOn :: (a -> b) -> [a] -> [a]
nubOn a -> b
f = ((b, a) -> a) -> [(b, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (b, a) -> a
forall a b. (a, b) -> b
snd ([(b, a)] -> [a]) -> ([a] -> [(b, a)]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((b, a) -> (b, a) -> Bool) -> [(b, a)] -> [(b, a)]
forall a. (a -> a -> Bool) -> [a] -> [a]
L.nubBy (b -> b -> Bool
forall a. Eq a => a -> a -> Bool
(==) (b -> b -> Bool) -> ((b, a) -> b) -> (b, a) -> (b, a) -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (b, a) -> b
forall a b. (a, b) -> a
fst) ([(b, a)] -> [(b, a)]) -> ([a] -> [(b, a)]) -> [a] -> [(b, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (b, a)) -> [a] -> [(b, a)]
forall a b. (a -> b) -> [a] -> [b]
map (\a
x -> let y :: b
y = a -> b
f a
x in b
y b -> (b, a) -> (b, a)
`seq` (b
y, a
x))
groupOn :: Eq b => (a -> b) -> [a] -> [[a]]
groupOn :: (a -> b) -> [a] -> [[a]]
groupOn a -> b
f = (a -> a -> Bool) -> [a] -> [[a]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
L.groupBy (b -> b -> Bool
forall a. Eq a => a -> a -> Bool
(==) (b -> b -> Bool) -> (a -> b) -> a -> a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on2` a -> b
f)
where t -> t -> t
(.*.) on2 :: (t -> t -> t) -> (p -> t) -> p -> p -> t
`on2` p -> t
g = \p
x -> let fx :: t
fx = p -> t
g p
x in \p
y -> t
fx t -> t -> t
.*. p -> t
g p
y
splitAt :: Integral n => n -> [a] -> ([a],[a])
splitAt :: n -> [a] -> ([a], [a])
splitAt n
n [a]
xs = n -> [a] -> ([a], [a])
forall n a. Integral n => n -> [a] -> ([a], [a])
L.genericSplitAt n
n [a]
xs
splitOn :: (Eq a) => [a] -> [a] -> [[a]]
splitOn :: [a] -> [a] -> [[a]]
splitOn [] [a]
_ = [Char] -> [[a]]
forall a. HasCallStack => [Char] -> a
error [Char]
"splitOn, needle may not be empty"
splitOn [a]
_ [] = [[]]
splitOn [a]
needle [a]
haystack = [a]
a [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: if [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
b then [] else [a] -> [a] -> [[a]]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn [a]
needle ([a] -> [[a]]) -> [a] -> [[a]]
forall a b. (a -> b) -> a -> b
$ Word -> [a] -> [a]
forall a. Word -> [a] -> [a]
drop ([a] -> Word
forall (t :: * -> *) a. Foldable t => t a -> Word
length [a]
needle) [a]
b
where ([a]
a,[a]
b) = [a] -> [a] -> ([a], [a])
forall a. Eq a => [a] -> [a] -> ([a], [a])
breakOn [a]
needle [a]
haystack
split :: (a -> Bool) -> [a] -> [[a]]
split :: (a -> Bool) -> [a] -> [[a]]
split a -> Bool
_ [] = [[]]
split a -> Bool
f (a
x:[a]
xs) | a -> Bool
f a
x = [] [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: (a -> Bool) -> [a] -> [[a]]
forall a. (a -> Bool) -> [a] -> [[a]]
split a -> Bool
f [a]
xs
split a -> Bool
f (a
x:[a]
xs) | ~([a]
y:[[a]]
ys) <- (a -> Bool) -> [a] -> [[a]]
forall a. (a -> Bool) -> [a] -> [[a]]
split a -> Bool
f [a]
xs = (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
y) [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: [[a]]
ys
breakOn :: Eq a => [a] -> [a] -> ([a], [a])
breakOn :: [a] -> [a] -> ([a], [a])
breakOn [a]
needle [a]
haystack
| [a]
needle [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`L.isPrefixOf` [a]
haystack = ([], [a]
haystack)
breakOn [a]
_ [] = ([], [])
breakOn [a]
needle (a
x:[a]
xs) = ([a] -> [a]) -> ([a], [a]) -> ([a], [a])
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:) (([a], [a]) -> ([a], [a])) -> ([a], [a]) -> ([a], [a])
forall a b. (a -> b) -> a -> b
$ [a] -> [a] -> ([a], [a])
forall a. Eq a => [a] -> [a] -> ([a], [a])
breakOn [a]
needle [a]
xs