-- | -- Module : Foundation.Collection.List -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : portable -- module Foundation.Collection.List ( wordsWhen , revTake , revDrop , revSplitAt , uncons , unsnoc ) where import qualified Data.List import Data.Tuple (swap) import Foundation.Internal.Base import Foundation.Numerical -- | Simple helper to split a list repeatly when the predicate match wordsWhen :: (x -> Bool) -> [x] -> [[x]] wordsWhen _ [] = [] wordsWhen p is = loop is where loop s = let (w, s') = Data.List.break p s in case s' of [] -> [w] _:xs -> w : loop xs revTake :: Int -> [a] -> [a] revTake n l = Data.List.drop (len - n) l where len = Data.List.length l revDrop :: Int -> [a] -> [a] revDrop n l = Data.List.take (len - n) l where len = Data.List.length l revSplitAt :: Int -> [a] -> ([a],[a]) revSplitAt n l = swap $ Data.List.splitAt (len - n) l where len = Data.List.length l uncons :: [a] -> Maybe (a, [a]) uncons [] = Nothing uncons (x:xs) = Just (x,xs) unsnoc :: [a] -> Maybe ([a], a) unsnoc [] = Nothing unsnoc [x] = Just ([], x) unsnoc [x,y] = Just ([x], y) unsnoc (x:xs@(_:_)) = Just $ loop [x] xs where loop acc [y] = (Data.List.reverse acc, y) loop acc (y:ys) = loop (y:acc) ys loop _ _ = error "impossible"