1-- | 2-- Module : Foundation.Collection.List 3-- License : BSD-style 4-- Maintainer : Vincent Hanquez <vincent@snarc.org> 5-- Stability : experimental 6-- Portability : portable 7-- 8module Foundation.Collection.List 9 ( wordsWhen 10 , revTake 11 , revDrop 12 , revSplitAt 13 , breakEnd 14 , uncons 15 , unsnoc 16 ) where 17 18import qualified Data.List 19import Data.Tuple (swap) 20import Basement.Compat.Base 21import Foundation.Numerical 22 23-- | Simple helper to split a list repeatly when the predicate match 24wordsWhen :: (x -> Bool) -> [x] -> [[x]] 25wordsWhen _ [] = [[]] 26wordsWhen p is = loop is 27 where 28 loop s = 29 let (w, s') = Data.List.break p s 30 in case s' of 31 [] -> [w] 32 _:xs -> w : loop xs 33 34revTake :: Int -> [a] -> [a] 35revTake n l = Data.List.drop (len - n) l 36 where 37 len = Data.List.length l 38 39revDrop :: Int -> [a] -> [a] 40revDrop n l = Data.List.take (len - n) l 41 where 42 len = Data.List.length l 43 44revSplitAt :: Int -> [a] -> ([a],[a]) 45revSplitAt n l = swap $ Data.List.splitAt (len - n) l 46 where 47 len = Data.List.length l 48 49breakEnd :: (a -> Bool) -> [a] -> ([a], [a]) 50breakEnd predicate l = 51 let (l1,l2) = Data.List.break predicate (Data.List.reverse l) 52 in if Data.List.null l2 then (l, []) else (Data.List.reverse l2, Data.List.reverse l1) 53 54uncons :: [a] -> Maybe (a, [a]) 55uncons [] = Nothing 56uncons (x:xs) = Just (x,xs) 57 58unsnoc :: [a] -> Maybe ([a], a) 59unsnoc [] = Nothing 60unsnoc [x] = Just ([], x) 61unsnoc [x,y] = Just ([x], y) 62unsnoc (x:xs@(_:_)) = Just $ loop [x] xs 63 where 64 loop acc [y] = (Data.List.reverse acc, y) 65 loop acc (y:ys) = loop (y:acc) ys 66 loop _ _ = error "impossible" 67