module Data.BAByNF.Util.List ( drainOnce , drainIf , drainWhile , lsplitWhenNot , rsplitWhenNot , lstrip , rstrip , lrsplitWhenNot ) where drainOnce :: [a] -> [a] -> ([a], [a]) drainOnce :: forall a. [a] -> [a] -> ([a], [a]) drainOnce [a] from [a] to = case [a] from of [] -> ([a] from, [a] to) a x:[a] xs -> ([a] xs, a xa -> [a] -> [a] forall a. a -> [a] -> [a] :[a] to) drainIf :: [a] -> [a] -> (a -> Bool) -> Maybe ([a], [a]) drainIf :: forall a. [a] -> [a] -> (a -> Bool) -> Maybe ([a], [a]) drainIf [a] from [a] to a -> Bool cond = case [a] from of [] -> Maybe ([a], [a]) forall a. Maybe a Nothing a x:[a] xs -> if a -> Bool cond a x then ([a], [a]) -> Maybe ([a], [a]) forall a. a -> Maybe a Just ([a] xs, a xa -> [a] -> [a] forall a. a -> [a] -> [a] :[a] to) else Maybe ([a], [a]) forall a. Maybe a Nothing drainWhile :: [a] -> [a] -> (a -> Bool) -> ([a], [a]) drainWhile :: forall a. [a] -> [a] -> (a -> Bool) -> ([a], [a]) drainWhile [a] from [a] to a -> Bool cond = case [a] -> [a] -> (a -> Bool) -> Maybe ([a], [a]) forall a. [a] -> [a] -> (a -> Bool) -> Maybe ([a], [a]) drainIf [a] from [a] to a -> Bool cond of Just ([a] from', [a] to') -> [a] -> [a] -> (a -> Bool) -> ([a], [a]) forall a. [a] -> [a] -> (a -> Bool) -> ([a], [a]) drainWhile [a] from' [a] to' a -> Bool cond Maybe ([a], [a]) Nothing -> ([a] from, [a] to) lsplitWhenNot :: [a] -> (a -> Bool) -> ([a], [a]) lsplitWhenNot :: forall a. [a] -> (a -> Bool) -> ([a], [a]) lsplitWhenNot [a] l a -> Bool matches = case [a] l of [] -> ([], []) (a focus:[a] rest) -> if a -> Bool matches a focus then let ([a] prefixTail, [a] suffix) = [a] -> (a -> Bool) -> ([a], [a]) forall a. [a] -> (a -> Bool) -> ([a], [a]) lsplitWhenNot [a] rest a -> Bool matches in (a focusa -> [a] -> [a] forall a. a -> [a] -> [a] :[a] prefixTail, [a] suffix) else ([], [a] l) rsplitWhenNot :: [a] -> (a -> Bool) -> ([a], [a]) rsplitWhenNot :: forall a. [a] -> (a -> Bool) -> ([a], [a]) rsplitWhenNot [a] l a -> Bool matches = (a -> ([a], [a]) -> ([a], [a])) -> ([a], [a]) -> [a] -> ([a], [a]) forall a b. (a -> b -> b) -> b -> [a] -> b forall (t :: * -> *) a b. Foldable t => (a -> b -> b) -> b -> t a -> b foldr a -> ([a], [a]) -> ([a], [a]) fn ([], []) [a] l where fn :: a -> ([a], [a]) -> ([a], [a]) fn a x ([a], [a]) acc = case ([a], [a]) acc of ([], [a] back) | a -> Bool matches a x -> ([], a xa -> [a] -> [a] forall a. a -> [a] -> [a] :[a] back) | Bool otherwise -> ([a x], [a] back) ([a] front, [a] back) -> (a xa -> [a] -> [a] forall a. a -> [a] -> [a] :[a] front, [a] back) rstrip :: [a] -> (a -> Bool) -> [a] rstrip :: forall a. [a] -> (a -> Bool) -> [a] rstrip [a] l a -> Bool matches = (a -> [a] -> [a]) -> [a] -> [a] -> [a] forall a b. (a -> b -> b) -> b -> [a] -> b forall (t :: * -> *) a b. Foldable t => (a -> b -> b) -> b -> t a -> b foldr a -> [a] -> [a] fn [] [a] l where fn :: a -> [a] -> [a] fn a x [a] acc = case [a] acc of [] | a -> Bool matches a x -> [] | Bool otherwise -> [a x] [a] _ -> a xa -> [a] -> [a] forall a. a -> [a] -> [a] :[a] acc lstrip :: [a] -> (a -> Bool) -> [a] lstrip :: forall a. [a] -> (a -> Bool) -> [a] lstrip [a] l a -> Bool matches = case [a] l of [] -> [] a x:[a] xs | a -> Bool matches a x -> [a] -> (a -> Bool) -> [a] forall a. [a] -> (a -> Bool) -> [a] lstrip [a] xs a -> Bool matches | Bool otherwise -> [a] l lrsplitWhenNot :: Show a => [a] -> (a -> Bool) -> ([a], [a], [a]) lrsplitWhenNot :: forall a. Show a => [a] -> (a -> Bool) -> ([a], [a], [a]) lrsplitWhenNot [a] x a -> Bool matches = let ([a] l, [a] x') = [a] -> (a -> Bool) -> ([a], [a]) forall a. [a] -> (a -> Bool) -> ([a], [a]) lsplitWhenNot [a] x a -> Bool matches ([a] m, [a] r) = [a] -> (a -> Bool) -> ([a], [a]) forall a. [a] -> (a -> Bool) -> ([a], [a]) rsplitWhenNot [a] x' a -> Bool matches in ([a] l, [a] m, [a] r)