module Foundation.Collection.List
( wordsWhen
, revTake
, revDrop
, revSplitAt
, breakEnd
, uncons
, unsnoc
) where
import qualified Data.List
import Data.Tuple (swap)
import Basement.Compat.Base
import Foundation.Numerical
wordsWhen :: (x -> Bool) -> [x] -> [[x]]
wordsWhen :: (x -> Bool) -> [x] -> [[x]]
wordsWhen x -> Bool
_ [] = [[]]
wordsWhen x -> Bool
p [x]
is = [x] -> [[x]]
loop [x]
is
where
loop :: [x] -> [[x]]
loop [x]
s =
let ([x]
w, [x]
s') = (x -> Bool) -> [x] -> ([x], [x])
forall a. (a -> Bool) -> [a] -> ([a], [a])
Data.List.break x -> Bool
p [x]
s
in case [x]
s' of
[] -> [[x]
w]
x
_:[x]
xs -> [x]
w [x] -> [[x]] -> [[x]]
forall a. a -> [a] -> [a]
: [x] -> [[x]]
loop [x]
xs
revTake :: Int -> [a] -> [a]
revTake :: Int -> [a] -> [a]
revTake Int
n [a]
l = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
Data.List.drop (Int
len Int -> Int -> Difference Int
forall a. Subtractive a => a -> a -> Difference a
- Int
n) [a]
l
where
len :: Int
len = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Data.List.length [a]
l
revDrop :: Int -> [a] -> [a]
revDrop :: Int -> [a] -> [a]
revDrop Int
n [a]
l = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
Data.List.take (Int
len Int -> Int -> Difference Int
forall a. Subtractive a => a -> a -> Difference a
- Int
n) [a]
l
where
len :: Int
len = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Data.List.length [a]
l
revSplitAt :: Int -> [a] -> ([a],[a])
revSplitAt :: Int -> [a] -> ([a], [a])
revSplitAt Int
n [a]
l = ([a], [a]) -> ([a], [a])
forall a b. (a, b) -> (b, a)
swap (([a], [a]) -> ([a], [a])) -> ([a], [a]) -> ([a], [a])
forall a b. (a -> b) -> a -> b
$ Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
Data.List.splitAt (Int
len Int -> Int -> Difference Int
forall a. Subtractive a => a -> a -> Difference a
- Int
n) [a]
l
where
len :: Int
len = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Data.List.length [a]
l
breakEnd :: (a -> Bool) -> [a] -> ([a], [a])
breakEnd :: (a -> Bool) -> [a] -> ([a], [a])
breakEnd a -> Bool
predicate [a]
l =
let ([a]
l1,[a]
l2) = (a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
Data.List.break a -> Bool
predicate ([a] -> [a]
forall a. [a] -> [a]
Data.List.reverse [a]
l)
in if [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
Data.List.null [a]
l2 then ([a]
l, []) else ([a] -> [a]
forall a. [a] -> [a]
Data.List.reverse [a]
l2, [a] -> [a]
forall a. [a] -> [a]
Data.List.reverse [a]
l1)
uncons :: [a] -> Maybe (a, [a])
uncons :: [a] -> Maybe (a, [a])
uncons [] = Maybe (a, [a])
forall a. Maybe a
Nothing
uncons (a
x:[a]
xs) = (a, [a]) -> Maybe (a, [a])
forall a. a -> Maybe a
Just (a
x,[a]
xs)
unsnoc :: [a] -> Maybe ([a], a)
unsnoc :: [a] -> Maybe ([a], a)
unsnoc [] = Maybe ([a], a)
forall a. Maybe a
Nothing
unsnoc [a
x] = ([a], a) -> Maybe ([a], a)
forall a. a -> Maybe a
Just ([], a
x)
unsnoc [a
x,a
y] = ([a], a) -> Maybe ([a], a)
forall a. a -> Maybe a
Just ([a
x], a
y)
unsnoc (a
x:xs :: [a]
xs@(a
_:[a]
_)) = ([a], a) -> Maybe ([a], a)
forall a. a -> Maybe a
Just (([a], a) -> Maybe ([a], a)) -> ([a], a) -> Maybe ([a], a)
forall a b. (a -> b) -> a -> b
$ [a] -> [a] -> ([a], a)
forall a. [a] -> [a] -> ([a], a)
loop [a
x] [a]
xs
where
loop :: [a] -> [a] -> ([a], a)
loop [a]
acc [a
y] = ([a] -> [a]
forall a. [a] -> [a]
Data.List.reverse [a]
acc, a
y)
loop [a]
acc (a
y:[a]
ys) = [a] -> [a] -> ([a], a)
loop (a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
acc) [a]
ys
loop [a]
_ [a]
_ = [Char] -> ([a], a)
forall a. HasCallStack => [Char] -> a
error [Char]
"impossible"