{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE Safe #-} module Util.List where import Control.Category (Category (..)) import Control.Applicative import Data.Bool import Data.Either (Either (..)) import Data.List.NonEmpty (NonEmpty (..)) import Data.Maybe (Maybe (..)) import Numeric.Natural import Util splitWhen :: (a -> Bool) -> [a] -> NonEmpty [a] splitWhen p = go where go = \ case [] -> []:|[] a:(go -> as:|ass) | p a -> []:|as:ass | True -> (a:as):|ass padLeft :: Natural -> a -> [a] -> [a] padLeft n a as = dropLengthOf as (replicate n a) <|> as where dropLengthOf [] as = as dropLengthOf _ [] = [] dropLengthOf (_:bs) (_:as) = dropLengthOf bs as zipWithRemaining :: (a -> b -> c) -> [a] -> [b] -> ([c], Maybe (Either (NonEmpty a) (NonEmpty b))) zipWithRemaining f = go id where go k [] [] = (k [], Nothing) go k [] (b:bs) = (k [], Just (Right (b:|bs))) go k (a:as) [] = (k [], Just (Left (a:|as))) go k (a:as) (b:bs) = go (k . (f a b :)) as bs