module Data.List.Extra.Drop where

-- | 'dropWhile' except keep the first of the dropped elements.
--
dropWhile1 :: (a -> Bool) -> [a] -> [a]
dropWhile1 :: forall a. (a -> Bool) -> [a] -> [a]
dropWhile1 a -> Bool
_ [] = []
dropWhile1 a -> Bool
p (a
x:[a]
xs)
  | a -> Bool
p a
x       = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile a -> Bool
p [a]
xs
  | Bool
otherwise = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
xs

-- | 'dropWhileEnd' except keep the first of the dropped elements.
--
dropWhileEnd1 :: (a -> Bool) -> [a] -> [a]
dropWhileEnd1 :: forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd1 a -> Bool
p = [a] -> [a]
go
  where
  -- State where @p@ isn't holding atm.
  go :: [a] -> [a]
go = \case
     []   -> []
     a
x:[a]
xs -> a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: if a -> Bool
p a
x then [a] -> [a] -> [a]
go' [] [a]
xs else [a] -> [a]
go [a]
xs
  -- State where @p@ is holding atm.
  -- The accumulator holds the elements where @p@ holds (but the first of these).
  go' :: [a] -> [a] -> [a]
go' [a]
acc = \case
    []   -> []
    a
x:[a]
xs -> if a -> Bool
p a
x then [a] -> [a] -> [a]
go' (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
acc) [a]
xs else [a] -> [a]
forall a. [a] -> [a]
reverse [a]
acc [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
go [a]
xs