Karya, built on 2023-08-29T07:47:28 (patch 7a412d5d6ba4968ca4155ef276a062ccdeb9109a)
Safe HaskellSafe-Inferred

Util.Lists

Description

Functions to operate on lists.

Synopsis

Documentation

type NonNull a = [a] Source #

This is just a list, but is documentation that a return value will never be null, or an argument should never be null. This is for cases where NonEmpty is too annoying to work with.

head :: [a] -> Maybe.Maybe a Source #

Total variants of unsafe list operations.

tail :: [a] -> Maybe.Maybe [a] Source #

last :: [a] -> Maybe.Maybe a Source #

unsnoc :: [a] -> Maybe.Maybe ([a], a) Source #

List initial and final element, if any.

indexing

at :: [a] -> Int -> Maybe.Maybe a Source #

Get xs !! n, but return Nothing if the index is out of range.

insertAt :: Int -> a -> [a] -> [a] Source #

Insert x into xs at index i. If i is out of range, insert at the beginning or end of the list.

removeAt :: Int -> [a] -> [a] Source #

Remove the element at the given index. Do nothing if the index is out of range.

takeAt :: Int -> [a] -> Maybe.Maybe (a, [a]) Source #

Like removeAt but return the removed element as well.

modifyAt :: Int -> (a -> a) -> [a] -> [a] Source #

Modify element at an index by applying a function to it. If the index is out of range, nothing happens.

findModify :: (a -> Bool) -> (a -> a) -> [a] -> Maybe.Maybe [a] Source #

Find an element, then change it. Return Nothing if the element wasn't found.

updateAt :: a -> Int -> (Maybe.Maybe a -> a) -> [a] -> [a] Source #

Similar to modifyAt, but will insert an element for an out of range positive index. The list will be extended with deflt, and the modify function passed a Nothing.

move :: Int -> Int -> [a] -> Maybe.Maybe [a] Source #

Move an element from one index to another, or Nothing if the from index was out of range.

enumeration

range :: (Num a, Ord.Ord a) => a -> a -> a -> [a] Source #

Enumerate an inclusive range. Uses multiplication instead of successive addition to avoid loss of precision.

Also it doesn't require an Enum instance.

range' :: (Num a, Ord.Ord a) => a -> a -> a -> [a] Source #

Enumerate a half-open range.

rangeEnd :: (Num a, Ord.Ord a) => a -> a -> a -> [a] Source #

Like range, but always includes the end, even if it doesn't line up on a step.

range_ :: Num a => a -> a -> [a] Source #

Infinite range.

transformation

keyOn :: (a -> k) -> [a] -> [(k, a)] Source #

keyOnSnd :: (a -> k) -> [a] -> [(a, k)] Source #

keyOnJust :: (a -> Maybe.Maybe k) -> [a] -> [(k, a)] Source #

firstLast :: (a -> a) -> (a -> a) -> [a] -> [a] Source #

Apply a function to the first and last elements. Middle elements are unchanged. A null or singleton list is also unchanged.

mapMaybeFst :: (a -> Maybe.Maybe a2) -> [(a, b)] -> [(a2, b)] Source #

Filter on the fst values returning Just.

mapMaybeSnd :: (b -> Maybe.Maybe b2) -> [(a, b)] -> [(a, b2)] Source #

Filter on the snd values returning Just.

mapHead :: (a -> a) -> [a] -> [a] Source #

mapTail :: (a -> a) -> [a] -> [a] Source #

mapHeadTail :: (a -> b) -> (a -> b) -> [a] -> [b] Source #

mapInit :: (a -> a) -> [a] -> [a] Source #

mapLast :: (a -> a) -> [a] -> [a] Source #

scanlOn :: (accum -> key -> accum) -> (a -> key) -> accum -> [a] -> [(accum, a)] Source #

This is like scanl, but you can scan with a key function. E.g. to accumulate line lengths: scanlOn length (+) 0.

min / max

minOn :: Ord.Ord k => (a -> k) -> a -> a -> a Source #

maxOn :: Ord.Ord k => (a -> k) -> a -> a -> a Source #

minimumOn :: Ord.Ord k => (a -> k) -> [a] -> Maybe.Maybe a Source #

maximumOn :: Ord.Ord k => (a -> k) -> [a] -> Maybe.Maybe a Source #

ordered lists

insertOn :: Ord.Ord k => (a -> k) -> a -> [a] -> [a] Source #

sortOn :: Ord.Ord k => (a -> k) -> [a] -> [a] Source #

Stable sort on a cheap key function. Different from List.sortOn, which is for an expensive key function.

reverseSortOn :: Ord.Ord b => (a -> b) -> [a] -> [a] Source #

Like sortOn, but sort highest-to-lowest.

merge :: Ord.Ord a => [a] -> [a] -> [a] Source #

Merge sorted lists. If two elements compare equal, the one from the left list comes first.

mergeBy :: (a -> a -> Ord.Ordering) -> [a] -> [a] -> [a] Source #

mergeOn :: Ord.Ord k => (a -> k) -> [a] -> [a] -> [a] Source #

mergeLists :: Ord.Ord k => (a -> k) -> [[a]] -> [a] Source #

mergeAscLists :: Ord.Ord k => (a -> k) -> [[a]] -> [a] Source #

If the heads of the sublists are also sorted I can be lazy in the list of sublists too. This version is optimized for minimal overlap.

grouping

adjacent

groupAdjacent :: Eq key => (a -> key) -> [a] -> [NonNull a] Source #

This is just List.groupBy except with a key function.

keyedGroupAdjacent :: Eq key => (a -> key) -> [a] -> [(key, NonNull a)] Source #

Like groupAdjacent, but include the key.

groupAdjacentFst :: Eq a => [(a, b)] -> [(a, NonNull b)] Source #

groupAdjacentSnd :: Eq b => [(a, b)] -> [(NonNull a, b)] Source #

sort

keyedGroupSort Source #

Arguments

:: Ord.Ord key 
=> (a -> key) 
-> [a] 
-> [(key, NonNull a)]

Sorted by key. The NonNull group is in the same order as the input.

Group the unsorted list into (key x, xs) where all xs compare equal after key is applied to them.

groupFst :: Ord.Ord a => [(a, b)] -> [(a, NonNull b)] Source #

Similar to keyedGroupSort, but key on the fst element, and strip the key out of the groups.

groupSnd :: Ord.Ord b => [(a, b)] -> [(NonNull a, b)] Source #

Like groupFst, but group on the snd element.

groupSort :: Ord.Ord key => (a -> key) -> [a] -> [NonNull a] Source #

Like List.groupBy, but the list doesn't need to be sorted, and use a key function instead of equality. The list is sorted by the key, and the groups appear in their original order in the input list.

stable

groupStableWith :: (a -> a -> Bool) -> [a] -> [NonEmpty a] Source #

Group each element with all the other elements that compare equal to it. The heads of the groups appear in their original order.

groupStable :: Eq key => (a -> key) -> [a] -> [NonEmpty a] Source #

groupStableWith but with a key function.

keyedGroupStable :: Eq key => (a -> key) -> [a] -> [(key, [a])] Source #

zipping

zipNext :: [a] -> [(a, Maybe.Maybe a)] Source #

Pair each element with the following element. The last element is paired with Nothing. Like zip xs (drop 1 xs ++ [Nothing]) but only traverses xs once.

zipNexts :: [a] -> [(a, [a])] Source #

zipPrev :: [a] -> [(Maybe.Maybe a, a)] Source #

zipNeighbors :: [a] -> [(Maybe.Maybe a, a, Maybe.Maybe a)] Source #

Like zipNext but with both preceding and following elements.

zipRemainder :: [a] -> [b] -> ([(a, b)], Either.Either [a] [b]) Source #

This is like zip, but it returns the remainder of the longer argument instead of discarding it.

zipper :: [a] -> [a] -> [([a], [a])] Source #

Return the reversed inits paired with the tails. This is like a zipper moving focus along the input list.

Paired

data Paired a b Source #

Constructors

First !a 
Second !b 
Both !a !b 

Instances

Instances details
Bifunctor Paired Source # 
Instance details

Defined in Util.Lists

Methods

bimap :: (a -> b) -> (c -> d) -> Paired a c -> Paired b d #

first :: (a -> b) -> Paired a c -> Paired b c #

second :: (b -> c) -> Paired a b -> Paired a c #

(Show a, Show b) => Show (Paired a b) Source # 
Instance details

Defined in Util.Lists

Methods

showsPrec :: Int -> Paired a b -> ShowS #

show :: Paired a b -> String #

showList :: [Paired a b] -> ShowS #

(Eq a, Eq b) => Eq (Paired a b) Source # 
Instance details

Defined in Util.Lists

Methods

(==) :: Paired a b -> Paired a b -> Bool #

(/=) :: Paired a b -> Paired a b -> Bool #

(Pretty a, Pretty b) => Pretty (Paired a b) Source # 
Instance details

Defined in Util.Pretty

Methods

pretty :: Paired a b -> Text Source #

format :: Paired a b -> Doc Source #

formatList :: [Paired a b] -> Doc Source #

partitionPaired :: [Paired a b] -> ([a], [b]) Source #

zipPadded :: [a] -> [b] -> [Paired a b] Source #

Like zip, but emit Firsts or Seconds if the list lengths are unequal.

zipPaddedFst :: [a] -> [b] -> [(Maybe.Maybe a, b)] Source #

Like zip, but the first list is padded with Nothings.

zipPaddedSnd :: [a] -> [b] -> [(a, Maybe.Maybe b)] Source #

Like zip, but the second list is padded with Nothings.

diff :: (a -> b -> Bool) -> [a] -> [b] -> [Paired a b] Source #

Perform a Meyes diff.

diffEither :: (a -> b -> Bool) -> [a] -> [b] -> [Either.Either a b] Source #

Left if the val was in the left list but not the right, Right for the converse.

diffIndex :: (a -> b -> Bool) -> [a] -> [b] -> [(Int, Paired a b)] Source #

This is like diff, except that the index of each pair in the right list is included. So the index is where you should delete or add the element to turn as into bs:

  • (i, Second b), i is the position of b in bs.
  • (i, First a), i is where a was deleted from bs.

diffIndexOn :: Eq k => (a -> k) -> [a] -> [a] -> [(Int, Paired a a)] Source #

pairSorted :: Ord.Ord k => [(k, a)] -> [(k, b)] -> [(k, Paired a b)] Source #

Pair up two lists of sorted pairs by their first element.

pairSortedOn :: Ord.Ord k => (a -> k) -> (b -> k) -> [a] -> [b] -> [Paired a b] Source #

Like pairSorted, but use a key function, and omit the extracted key.

pairSortedOn1 :: Ord.Ord k => (a -> k) -> [a] -> [a] -> [Paired a a] Source #

Like pairSorted, but use a key function, and omit the extracted key.

pairOn1 :: Ord.Ord k => (a -> k) -> [a] -> [a] -> [Paired a a] Source #

Like pairOn, but when the lists have the same type.

partition

partition2 :: (a -> Bool) -> (a -> Bool) -> [a] -> ([a], [a], [a]) Source #

Like List.partition, but partition by two functions consecutively.

partitionOn :: (a -> Maybe.Maybe b) -> [a] -> ([b], [a]) Source #

Partition and transform at the same time.

sublists

chunked :: Int -> [a] -> [[a]] Source #

Split into groups of a certain size.

rotate :: [[a]] -> [[a]] Source #

Take a list of rows to a list of columns. This is like a zip except for variable-length lists. Similar to zip, the result is trimmed to the length of the shortest row.

List.transpose is similar, but it skips missing elements, instead of truncating all to the shortest. Skipping means you lose what column the element came from.

rotate2 :: [[a]] -> [[Maybe.Maybe a]] Source #

Similar to rotate, except that the result is the length of the longest row and missing columns are Nothing. Analogous to zip_padded.

prefix / suffix

dropBefore :: Ord.Ord key => (a -> key) -> key -> [a] -> [a] Source #

Drop until the last element before or equal to the given element.

dropPrefix :: Eq a => [a] -> [a] -> ([a], Bool) Source #

If the list doesn't have the given prefix, return the original list and False. Otherwise, strip it off and return True. List.stripPrefix is an alternate version.

dropSuffix :: Eq a => [a] -> [a] -> ([a], Bool) Source #

permutations

cartesian :: [[a]] -> [[a]] Source #

The cartesian product of a list of lists. E.g. [[1, 2], [3, 4]] -> [[1, 3], [1, 4], [2, 3], [2, 4]].

enumeration

enumerate :: [a] -> [(Int, a)] Source #

sublists

takeEnd :: Int -> [a] -> [a] Source #

dropEnd :: Int -> [a] -> [a] Source #

takeWhileEnd :: (a -> Bool) -> [a] -> [a] Source #

split / join

splitWith :: (a -> Maybe.Maybe b) -> [a] -> ([a], [(b, [a])]) Source #

breakWith :: (a -> Maybe.Maybe b) -> [a] -> ([a], Maybe.Maybe (b, [a])) Source #

transform

mapAccumLM :: Monad m => (state -> x -> m (state, y)) -> state -> [x] -> m (state, [y]) Source #

Like List.mapAccumL, but monadic. Strict in the accumulator.

split and join

split :: Eq a => NonNull a -> [a] -> NonNull [a] Source #

Split xs on sep, dropping sep from the result.

join :: Monoid a => a -> [a] -> a Source #

Interspense a separator and concat.

splitBefore :: (a -> Bool) -> [a] -> [[a]] Source #

Split before places where the function matches.

> splitBefore (==1) [1, 2, 1]
[[], [1, 2], [1]]

splitBetween :: (a -> a -> Bool) -> [a] -> [[a]] Source #

Split the list on the points where the given function returns true.

This is similar to groupBy, except this is defined to compare adjacent elements. groupBy actually compares to the first element of each group. E.g. you can't group numeric runs with groupBy (a b -> b > a+1).

span and break

spanWhile :: (a -> Maybe.Maybe b) -> [a] -> ([b], [a]) Source #

Like span, but it can transform the spanned sublist.

duplicates

dropDups :: Eq k => (a -> k) -> [a] -> [a] Source #

Drop adjacent elts if they are equal after applying the key function. The first elt is kept.

dropWith :: (a -> a -> Bool) -> [a] -> [a] Source #

Filter out elts when the predicate is true for adjacent elts. The first elt is kept, and the later ones are dropped. This is like dropDups except it can compare two elements. E.g. dropWith (>=) will ensure the sequence is increasing.

partitionDups Source #

Arguments

:: Ord.Ord k 
=> (a -> k) 
-> [a] 
-> ([a], [(a, NonNull a)])

([unique], [(used_for_unique, [dups])])

Sort the input by the key, extract unique values, and also return the duplicates.

findDups :: Ord.Ord k => (a -> k) -> [a] -> [(a, NonEmpty a)] Source #

Find duplicate values. There are always at least 2 of each output.

dropInitialDups :: Eq k => (a -> k) -> [a] -> [a] Source #

Like dropDups, but keep the last adjacent equal elt instead of the first.

unique :: Ord.Ord a => [a] -> [a] Source #

uniqueOn :: Ord.Ord k => (a -> k) -> [a] -> [a] Source #

This is like dropDups, except that it's not limited to just adjacent elts. The output list is in the same order as the input.

uniqueSort :: Ord.Ord a => [a] -> [a] Source #

Like unique, but sort the list, and should be more efficient.

replace

replace :: Eq a => [a] -> [a] -> [a] -> [a] Source #

Replace sublist from with to in the given list.

replace1 :: Eq a => a -> [a] -> [a] -> [a] Source #

Replace occurrances of an element with zero or more other elements.

search

count :: Foldable t => (a -> Bool) -> t a -> Int Source #