module Data.List.Index
(
indexed,
deleteAt,
setAt,
modifyAt,
updateAt,
insertAt,
imap,
imapM, imapM_,
ifor, ifor_,
ifoldr, ifoldl, ifoldl',
iall, iany, iconcatMap,
ifilter, ipartition,
itakeWhile, idropWhile,
izipWith,
izipWithM, izipWithM_,
ifind,
ifindIndex,
ifindIndices,
izipWith3,
izipWith4,
izipWith5,
izipWith6,
izipWith7,
iforM, iforM_,
itraverse, itraverse_,
ireplicateM, ireplicateM_,
ifoldrM,
ifoldlM,
ifoldMap,
imapAccumR,
imapAccumL,
)
where
#if __GLASGOW_HASKELL__ >= 710
import GHC.Base (oneShot)
#define ONE_SHOT oneShot
#else
#define ONE_SHOT
#endif
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative
import Data.Traversable (sequenceA)
#endif
import Data.Foldable (sequenceA_)
import Data.Maybe
import Data.Monoid
import GHC.Exts
indexed :: [a] -> [(Int, a)]
indexed xs = go 0# xs
where
go i (a:as) = (I# i, a) : go (i +# 1#) as
go _ _ = []
indexedFB :: ((Int, a) -> t -> t) -> a -> (Int# -> t) -> Int# -> t
indexedFB c = \x cont i -> (I# i, x) `c` cont (i +# 1#)
deleteAt :: Int -> [a] -> [a]
deleteAt i ls
| i < 0 = ls
| otherwise = go i ls
where
go 0 (_:xs) = xs
go n (x:xs) = x : go (n1) xs
go _ [] = []
setAt :: Int -> a -> [a] -> [a]
setAt i a ls
| i < 0 = ls
| otherwise = go i ls
where
go 0 (_:xs) = a : xs
go n (x:xs) = x : go (n1) xs
go _ [] = []
modifyAt :: Int -> (a -> a) -> [a] -> [a]
modifyAt i f ls
| i < 0 = ls
| otherwise = go i ls
where
go 0 (x:xs) = f x : xs
go n (x:xs) = x : go (n1) xs
go _ [] = []
updateAt :: Int -> (a -> Maybe a) -> [a] -> [a]
updateAt i f ls
| i < 0 = ls
| otherwise = go i ls
where
go 0 (x:xs) = case f x of
Nothing -> xs
Just x' -> x' : xs
go n (x:xs) = x : go (n1) xs
go _ [] = []
insertAt :: Int -> a -> [a] -> [a]
insertAt i a ls
| i < 0 = ls
| otherwise = go i ls
where
go 0 xs = a : xs
go n (x:xs) = x : go (n1) xs
go _ [] = []
imap :: (Int -> a -> b) -> [a] -> [b]
imap f ls = go 0# ls
where
go i (x:xs) = f (I# i) x : go (i +# 1#) xs
go _ _ = []
imapFB
:: (b -> t -> t) -> (Int -> a -> b) -> a -> (Int# -> t) -> Int# -> t
imapFB c f = \x r k -> f (I# k) x `c` r (k +# 1#)
iconcatMap :: (Int -> a -> [b]) -> [a] -> [b]
iconcatMap f xs = build $ \c n ->
ifoldr (\i x b -> foldr c b (f i x)) n xs
ifoldMap :: Monoid m => (Int -> a -> m) -> [a] -> m
ifoldMap p ls = foldr go (\_ -> mempty) ls 0#
where go x r k = p (I# k) x <> r (k +# 1#)
iall :: (Int -> a -> Bool) -> [a] -> Bool
iall p ls = foldr go (\_ -> True) ls 0#
where go x r k = p (I# k) x && r (k +# 1#)
iany :: (Int -> a -> Bool) -> [a] -> Bool
iany p ls = foldr go (\_ -> False) ls 0#
where go x r k = p (I# k) x || r (k +# 1#)
imapM :: Monad m => (Int -> a -> m b) -> [a] -> m [b]
imapM f as = ifoldr k (return []) as
where
k i a r = do
x <- f i a
xs <- r
return (x:xs)
iforM :: Monad m => [a] -> (Int -> a -> m b) -> m [b]
iforM = flip imapM
itraverse :: Applicative m => (Int -> a -> m b) -> [a] -> m [b]
itraverse f as = ifoldr k (pure []) as
where
k i a r = (:) <$> f i a <*> r
ifor :: Applicative m => [a] -> (Int -> a -> m b) -> m [b]
ifor = flip itraverse
imapM_ :: Monad m => (Int -> a -> m b) -> [a] -> m ()
imapM_ f as = ifoldr k (return ()) as
where
k i a r = f i a >> r
iforM_ :: Monad m => [a] -> (Int -> a -> m b) -> m ()
iforM_ = flip imapM_
itraverse_ :: Applicative m => (Int -> a -> m b) -> [a] -> m ()
itraverse_ f as = ifoldr k (pure ()) as
where
k i a r = f i a *> r
ifor_ :: Applicative m => [a] -> (Int -> a -> m b) -> m ()
ifor_ = flip itraverse_
ireplicateM :: Applicative m => Int -> (Int -> m a) -> m [a]
ireplicateM cnt f = go 0
where
go !i | i >= cnt = pure []
| otherwise = (:) <$> f i <*> go (i + 1)
ireplicateM_ :: Monad m => Int -> (Int -> m a) -> m ()
ireplicateM_ cnt f = if cnt > 0 then go 0 else return ()
where
cnt_ = cnt1
go !i = if i == cnt_ then f i >> return () else f i >> go (i + 1)
ifoldr :: (Int -> a -> b -> b) -> b -> [a] -> b
ifoldr f z xs = foldr (\x g i -> f i x (g (i+1))) (const z) xs 0
ifoldrM :: Monad m => (Int -> a -> b -> m b) -> b -> [a] -> m b
ifoldrM f z xs = ifoldr k (return z) xs
where
k i a r = f i a =<< r
imapAccumR
:: (acc -> Int -> x -> (acc, y))
-> acc
-> [x]
-> (acc, [y])
imapAccumR f z xs =
foldr (\x g i -> let (a, ys) = g (i+1)
(a', y) = f a i x
in (a', y:ys))
(const (z, [])) xs 0
ifoldl :: forall a b. (b -> Int -> a -> b) -> b -> [a] -> b
ifoldl k z0 xs =
foldr (\(v::a) (fn :: (Int, b) -> b) ->
ONE_SHOT (\((!i)::Int, z::b) -> fn (i+1, k z i v)))
(snd :: (Int, b) -> b)
xs
(0, z0)
ifoldl' :: forall a b. (b -> Int -> a -> b) -> b -> [a] -> b
ifoldl' k z0 xs =
foldr (\(v::a) (fn :: (Int, b) -> b) ->
ONE_SHOT (\((!i)::Int, z::b) -> z `seq` fn (i+1, k z i v)))
(snd :: (Int, b) -> b)
xs
(0, z0)
ifoldlM :: Monad m => (b -> Int -> a -> m b) -> b -> [a] -> m b
ifoldlM f z xs = ifoldl k (return z) xs
where
k a i r = do a' <- a; f a' i r
imapAccumL
:: (acc -> Int -> x -> (acc, y))
-> acc
-> [x]
-> (acc, [y])
imapAccumL f z xs =
foldr (\(x::a) (r :: (Int,acc) -> (acc,[y])) ->
ONE_SHOT (\((!i)::Int, s::acc) ->
let (s', y) = f s i x
(s'', ys) = r (i+1, s')
in (s'', y:ys)))
((\(_, a) -> (a, [])) :: (Int,acc) -> (acc,[y]))
xs
(0, z)
ifilter :: (Int -> a -> Bool) -> [a] -> [a]
ifilter p ls = go 0# ls
where
go i (x:xs) | p (I# i) x = x : go (i +# 1#) xs
| otherwise = go (i +# 1#) xs
go _ _ = []
ifilterFB
:: (a -> t -> t) -> (Int -> a -> Bool) -> a -> (Int# -> t) -> Int# -> t
ifilterFB c p = \x r k ->
if p (I# k) x then x `c` r (k +# 1#) else r (k +# 1#)
itakeWhile :: (Int -> a -> Bool) -> [a] -> [a]
itakeWhile p ls = go 0# ls
where
go i (x:xs) | p (I# i) x = x : go (i +# 1#) xs
| otherwise = []
go _ _ = []
itakeWhileFB
:: (a -> t -> t) -> (Int -> a -> Bool) -> t -> a -> (Int# -> t) -> Int# -> t
itakeWhileFB c p n = \x r k ->
if p (I# k) x then x `c` r (k +# 1#) else n
idropWhile :: (Int -> a -> Bool) -> [a] -> [a]
idropWhile p ls = go 0# ls
where
go i (x:xs) | p (I# i) x = go (i +# 1#) xs
| otherwise = x:xs
go _ [] = []
ipartition :: (Int -> a -> Bool) -> [a] -> ([a],[a])
ipartition p xs = ifoldr (iselect p) ([],[]) xs
iselect :: (Int -> a -> Bool) -> Int -> a -> ([a], [a]) -> ([a], [a])
iselect p i x ~(ts,fs) | p i x = (x:ts,fs)
| otherwise = (ts, x:fs)
ifind :: (Int -> a -> Bool) -> [a] -> Maybe (Int, a)
ifind p ls = go 0# ls
where
go i (x:xs) | p (I# i) x = Just (I# i, x)
| otherwise = go (i +# 1#) xs
go _ _ = Nothing
ifindIndex :: (Int -> a -> Bool) -> [a] -> Maybe Int
ifindIndex p = listToMaybe . ifindIndices p
ifindIndices :: (Int -> a -> Bool) -> [a] -> [Int]
ifindIndices p ls = go 0# ls
where
go _ [] = []
go i (x:xs) | p (I# i) x = I# i : go (i +# 1#) xs
| otherwise = go (i +# 1#) xs
ifindIndicesFB
:: (Int -> t -> t) -> (Int -> a -> Bool) -> a -> (Int# -> t) -> Int# -> t
ifindIndicesFB c p = \x r k ->
if p (I# k) x then I# k `c` r (k +# 1#) else r (k +# 1#)
izipWith :: (Int -> a -> b -> c) -> [a] -> [b] -> [c]
izipWith fun xs ys = go 0# xs ys
where
go i (a:as) (b:bs) = fun (I# i) a b : go (i +# 1#) as bs
go _ _ _ = []
izipWithFB
:: (c -> t -> t) -> (Int -> a -> b -> c) -> a -> b -> (Int# -> t) -> Int# -> t
izipWithFB c fun = \x y cont i -> fun (I# i) x y `c` cont (i +# 1#)
foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c
foldr2 k z = go
where
go [] _ys = z
go _xs [] = z
go (x:xs) (y:ys) = k x y (go xs ys)
foldr2_left :: (a -> b -> c -> d) -> d -> a -> ([b] -> c) -> [b] -> d
foldr2_left _k z _x _r [] = z
foldr2_left k _z x r (y:ys) = k x y (r ys)
izipWith3
:: (Int -> a -> b -> c -> d)
-> [a] -> [b] -> [c] -> [d]
izipWith3 fun = go 0#
where
go i (a:as) (b:bs) (c:cs) =
fun (I# i) a b c : go (i +# 1#) as bs cs
go _ _ _ _ = []
izipWith4
:: (Int -> a -> b -> c -> d -> e)
-> [a] -> [b] -> [c] -> [d] -> [e]
izipWith4 fun = go 0#
where
go i (a:as) (b:bs) (c:cs) (d:ds) =
fun (I# i) a b c d : go (i +# 1#) as bs cs ds
go _ _ _ _ _ = []
izipWith5
:: (Int -> a -> b -> c -> d -> e -> f)
-> [a] -> [b] -> [c] -> [d] -> [e] -> [f]
izipWith5 fun = go 0#
where
go i (a:as) (b:bs) (c:cs) (d:ds) (e:es) =
fun (I# i) a b c d e : go (i +# 1#) as bs cs ds es
go _ _ _ _ _ _ = []
izipWith6
:: (Int -> a -> b -> c -> d -> e -> f -> g)
-> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g]
izipWith6 fun = go 0#
where
go i (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) =
fun (I# i) a b c d e f : go (i +# 1#) as bs cs ds es fs
go _ _ _ _ _ _ _ = []
izipWith7
:: (Int -> a -> b -> c -> d -> e -> f -> g -> h)
-> [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [h]
izipWith7 fun = go 0#
where
go i (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs) =
fun (I# i) a b c d e f g : go (i +# 1#) as bs cs ds es fs gs
go _ _ _ _ _ _ _ _ = []
izipWithM :: Applicative f => (Int -> a -> b -> f c) -> [a] -> [b] -> f [c]
izipWithM f as bs = sequenceA (izipWith f as bs)
izipWithM_ :: Applicative f => (Int -> a -> b -> f c) -> [a] -> [b] -> f ()
izipWithM_ f as bs = sequenceA_ (izipWith f as bs)