| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Haskus.Utils.List
Contents
Description
List utils
Synopsis
- at :: [a] -> Word -> Maybe a
- unsafeAt :: [a] -> Word -> a
- checkLength :: Word -> [a] -> Bool
- (++) :: [a] -> [a] -> [a]
- replicate :: Word -> a -> [a]
- drop :: Word -> [a] -> [a]
- length :: Foldable t => t a -> Word
- take :: Word -> [a] -> [a]
- chunksOf :: Word -> [a] -> [[a]]
- pick1 :: [a] -> [(a, [a])]
- enumList :: forall a. (Bounded a, Enum a) => [a]
- zipLeftWith :: (a -> b) -> [a] -> [(b, a)]
- zipRightWith :: (a -> b) -> [a] -> [(a, b)]
- partition :: (a -> Bool) -> [a] -> ([a], [a])
- nub :: Eq a => [a] -> [a]
- sort :: Ord a => [a] -> [a]
- intersperse :: a -> [a] -> [a]
- foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b
- head :: HasCallStack => [a] -> a
- tail :: HasCallStack => [a] -> [a]
- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
- repeat :: a -> [a]
- nubOn :: Eq b => (a -> b) -> [a] -> [a]
- nubBy :: (a -> a -> Bool) -> [a] -> [a]
- sortOn :: Ord b => (a -> b) -> [a] -> [a]
- sortBy :: (a -> a -> Ordering) -> [a] -> [a]
- groupOn :: Eq b => (a -> b) -> [a] -> [[a]]
- groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
- transpose :: [[a]] -> [[a]]
- (\\) :: Eq a => [a] -> [a] -> [a]
- intersect :: Eq a => [a] -> [a] -> [a]
- find :: Foldable t => (a -> Bool) -> t a -> Maybe a
- zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
- zip4 :: [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
- zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a, b, c, d, e)]
- zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]
- zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a, b, c, d, e, f, g)]
- stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]
- isPrefixOf :: Eq a => [a] -> [a] -> Bool
- deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
- isSuffixOf :: Eq a => [a] -> [a] -> Bool
- elem :: (Foldable t, Eq a) => a -> t a -> Bool
- notElem :: (Foldable t, Eq a) => a -> t a -> Bool
- splitAt :: Integral n => n -> [a] -> ([a], [a])
- split :: (a -> Bool) -> [a] -> [[a]]
- splitOn :: Eq a => [a] -> [a] -> [[a]]
- breakOn :: Eq a => [a] -> [a] -> ([a], [a])
Documentation
at :: [a] -> Word -> Maybe a Source #
Safely index into a list
>>>[0,1,2,3] `at` 10Nothing
>>>[0,1,2,3] `at` 2Just 2
checkLength :: Word -> [a] -> Bool Source #
Check that a list has the given length (support infinite lists)
(++) :: [a] -> [a] -> [a] infixr 5 #
Append two lists, i.e.,
[x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn] [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...]
If the first list is not finite, the result is the first list.
WARNING: This function takes linear time in the number of elements of the first list.
chunksOf :: Word -> [a] -> [[a]] Source #
Split a list into chunks of a given size. The last chunk may contain fewer than n elements.
>>>chunksOf 3 "my test"["my ","tes","t"]
>>>chunksOf 3 "mytest"["myt","est"]
>>>chunksOf 8 ""[]
> chunksOf 0 "test"
undefined
pick1 :: [a] -> [(a, [a])] Source #
Pick each element and return the element and the rest of the list
>>>pick1 [1,2,3,4][(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])]
enumList :: forall a. (Bounded a, Enum a) => [a] Source #
Get members of a bounded enum in a list
>>>:seti -XTypeApplications>>>data Letters = A | B | C | D deriving (Bounded,Enum,Show)>>>enumList @Letters[A,B,C,D]
zipLeftWith :: (a -> b) -> [a] -> [(b, a)] Source #
Zip left with something extracted from each value
>>>zipLeftWith odd [0..5][(False,0),(True,1),(False,2),(True,3),(False,4),(True,5)]
zipRightWith :: (a -> b) -> [a] -> [(a, b)] Source #
Zip right with something extracted from each value
>>>zipRightWith odd [0..5][(0,False),(1,True),(2,False),(3,True),(4,False),(5,True)]
partition :: (a -> Bool) -> [a] -> ([a], [a]) #
The partition function takes a predicate and a list, and returns the pair of lists of elements which do and do not satisfy the predicate, respectively; i.e.,
partition p xs == (filter p xs, filter (not . p) xs)
>>>partition (`elem` "aeiou") "Hello World!"("eoo","Hll Wrld!")
\(\mathcal{O}(n^2)\). The nub function removes duplicate elements from a list. In particular, it keeps only the first occurrence of each element. (The name nub means `essence'.) It is a special case of nubBy, which allows the programmer to supply their own equality test.
>>>nub [1,2,3,4,3,2,1,2,4,3,5][1,2,3,4,5]
If the order of outputs does not matter and there exists instance Ord a, it's faster to use map Data.List.NonEmpty.head . Data.List.NonEmpty.group . sort, which takes only \(\mathcal{O}(n \log n)\) time.
The sort function implements a stable sorting algorithm. It is a special case of sortBy, which allows the programmer to supply their own comparison function.
Elements are arranged from lowest to highest, keeping duplicates in the order they appeared in the input.
>>>sort [1,6,4,3,2,5][1,2,3,4,5,6]
The argument must be finite.
intersperse :: a -> [a] -> [a] #
\(\mathcal{O}(n)\). The intersperse function takes an element and a list and `intersperses' that element between the elements of the list. For example,
>>>intersperse ',' "abcde""a,b,c,d,e"
foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b #
Left-associative fold of a structure but with strict application of the operator.
This ensures that each step of the fold is forced to Weak Head Normal Form before being applied, avoiding the collection of thunks that would otherwise occur. This is often what you want to strictly reduce a finite structure to a single strict result (e.g. sum).
For a general Foldable structure this should be semantically identical to,
foldl' f z =foldl'f z .toList
Since: base-4.6.0.0
head :: HasCallStack => [a] -> a #
\(\mathcal{O}(1)\). Extract the first element of a list, which must be non-empty.
>>>head [1, 2, 3]1>>>head [1..]1>>>head []*** Exception: Prelude.head: empty list
WARNING: This function is partial. You can use case-matching, uncons or listToMaybe instead.
tail :: HasCallStack => [a] -> [a] #
\(\mathcal{O}(1)\). Extract the elements after the head of a list, which must be non-empty.
>>>tail [1, 2, 3][2,3]>>>tail [1][]>>>tail []*** Exception: Prelude.tail: empty list
WARNING: This function is partial. You can use case-matching or uncons instead.
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] #
\(\mathcal{O}(\min(m,n))\). zipWith generalises zip by zipping with the function given as the first argument, instead of a tupling function.
zipWith (,) xs ys == zip xs ys zipWith f [x1,x2,x3..] [y1,y2,y3..] == [f x1 y1, f x2 y2, f x3 y3..]
For example, is applied to two lists to produce the list of corresponding sums:zipWith (+)
>>>zipWith (+) [1, 2, 3] [4, 5, 6][5,7,9]
zipWith is right-lazy:
>>>let f = undefined>>>zipWith f [] undefined[]
zipWith is capable of list fusion, but it is restricted to its first list argument and its resulting list.
repeat x is an infinite list, with x the value of every element.
>>>repeat 17[17,17,17,17,17,17,17,17,17...
nubOn :: Eq b => (a -> b) -> [a] -> [a] Source #
A version of nub where the equality is done on some extracted value. nubOn f is equivalent to nubBy ((==) , but has the performance advantage of only evaluating on f)f once for each element in the input list.
sortOn :: Ord b => (a -> b) -> [a] -> [a] #
Sort a list by comparing the results of a key function applied to each element. is equivalent to sortOn f, but has the performance advantage of only evaluating sortBy (comparing f)f once for each element in the input list. This is called the decorate-sort-undecorate paradigm, or Schwartzian transform.
Elements are arranged from lowest to highest, keeping duplicates in the order they appeared in the input.
>>>sortOn fst [(2, "world"), (4, "!"), (1, "Hello")][(1,"Hello"),(2,"world"),(4,"!")]
The argument must be finite.
Since: base-4.8.0.0
sortBy :: (a -> a -> Ordering) -> [a] -> [a] #
The sortBy function is the non-overloaded version of sort. The argument must be finite.
>>>sortBy (\(a,_) (b,_) -> compare a b) [(2, "world"), (4, "!"), (1, "Hello")][(1,"Hello"),(2,"world"),(4,"!")]
The supplied comparison relation is supposed to be reflexive and antisymmetric, otherwise, e. g., for _ _ -> GT, the ordered list simply does not exist. The relation is also expected to be transitive: if it is not then sortBy might fail to find an ordered permutation, even if it exists.
groupOn :: Eq b => (a -> b) -> [a] -> [[a]] Source #
A version of group where the equality is done on some extracted value.
groupBy :: (a -> a -> Bool) -> [a] -> [[a]] #
The groupBy function is the non-overloaded version of group.
When a supplied relation is not transitive, it is important to remember that equality is checked against the first element in the group, not against the nearest neighbour:
>>>groupBy (\a b -> b - a < 5) [0..19][[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14],[15,16,17,18,19]]
It's often preferable to use Data.List.NonEmpty.groupBy, which provides type-level guarantees of non-emptiness of inner lists.
The transpose function transposes the rows and columns of its argument. For example,
>>>transpose [[1,2,3],[4,5,6]][[1,4],[2,5],[3,6]]
If some of the rows are shorter than the following rows, their elements are skipped:
>>>transpose [[10,11],[20],[],[30,31,32]][[10,20,30],[11,31],[32]]
For this reason the outer list must be finite; otherwise transpose hangs:
>>>transpose (repeat [])* Hangs forever *
(\\) :: Eq a => [a] -> [a] -> [a] infix 5 #
The \\ function is list difference (non-associative). In the result of xs \\ ys, the first occurrence of each element of ys in turn (if any) has been removed from xs. Thus (xs ++ ys) \\ xs == ys.
>>>"Hello World!" \\ "ell W""Hoorld!"
It is a special case of deleteFirstsBy, which allows the programmer to supply their own equality test.
The second list must be finite, but the first may be infinite.
>>>take 5 ([0..] \\ [2..4])[0,1,5,6,7]>>>take 5 ([0..] \\ [2..])* Hangs forever *
intersect :: Eq a => [a] -> [a] -> [a] #
The intersect function takes the list intersection of two lists. It is a special case of intersectBy, which allows the programmer to supply their own equality test. For example,
>>>[1,2,3,4] `intersect` [2,4,6,8][2,4]
If equal elements are present in both lists, an element from the first list will be used, and all duplicates from the second list quashed:
>>>import Data.Semigroup>>>intersect [Arg () "dog"] [Arg () "cow", Arg () "cat"][Arg () "dog"]
However if the first list contains duplicates, so will the result.
>>>"coot" `intersect` "heron""oo">>>"heron" `intersect` "coot""o"
If the second list is infinite, intersect either hangs or returns its first argument in full. Otherwise if the first list is infinite, intersect might be productive:
>>>intersect [100..] [0..][100,101,102,103...>>>intersect [0] [1..]* Hangs forever *>>>intersect [1..] [0]* Hangs forever *>>>intersect (cycle [1..3]) [2][2,2,2,2...
stripPrefix :: Eq a => [a] -> [a] -> Maybe [a] #
\(\mathcal{O}(\min(m,n))\). The stripPrefix function drops the given prefix from a list. It returns Nothing if the list did not start with the prefix given, or Just the list after the prefix, if it does.
>>>stripPrefix "foo" "foobar"Just "bar"
>>>stripPrefix "foo" "foo"Just ""
>>>stripPrefix "foo" "barfoo"Nothing
>>>stripPrefix "foo" "barfoobaz"Nothing
isPrefixOf :: Eq a => [a] -> [a] -> Bool #
\(\mathcal{O}(\min(m,n))\). The isPrefixOf function takes two lists and returns True iff the first list is a prefix of the second.
>>>"Hello" `isPrefixOf` "Hello World!"True>>>"Hello" `isPrefixOf` "Wello Horld!"False
For the result to be True, the first list must be finite; False, however, results from any mismatch:
>>>[0..] `isPrefixOf` [1..]False>>>[0..] `isPrefixOf` [0..99]False>>>[0..99] `isPrefixOf` [0..]True>>>[0..] `isPrefixOf` [0..]* Hangs forever *
isSuffixOf :: Eq a => [a] -> [a] -> Bool #
The isSuffixOf function takes two lists and returns True iff the first list is a suffix of the second.
>>>"ld!" `isSuffixOf` "Hello World!"True>>>"World" `isSuffixOf` "Hello World!"False
The second list must be finite; however the first list may be infinite:
>>>[0..] `isSuffixOf` [0..99]False>>>[0..99] `isSuffixOf` [0..]* Hangs forever *
elem :: (Foldable t, Eq a) => a -> t a -> Bool infix 4 #
Does the element occur in the structure?
Note: elem is often used in infix form.
Examples
Basic usage:
>>>3 `elem` []False
>>>3 `elem` [1,2]False
>>>3 `elem` [1,2,3,4,5]True
For infinite structures, the default implementation of elem terminates if the sought-after value exists at a finite distance from the left side of the structure:
>>>3 `elem` [1..]True
>>>3 `elem` ([4..] ++ [3])* Hangs forever *
Since: base-4.8.0.0
notElem :: (Foldable t, Eq a) => a -> t a -> Bool infix 4 #
notElem is the negation of elem.
Examples
Basic usage:
>>>3 `notElem` []True
>>>3 `notElem` [1,2]True
>>>3 `notElem` [1,2,3,4,5]False
For infinite structures, notElem terminates if the value exists at a finite distance from the left side of the structure:
>>>3 `notElem` [1..]False
>>>3 `notElem` ([4..] ++ [3])* Hangs forever *
Split
splitAt :: Integral n => n -> [a] -> ([a], [a]) Source #
splitAt n xs returns a tuple where first element is xs prefix of length n and second element is the remainder of the list:
splitAt 6 "Hello World!" == ("Hello ","World!") splitAt 3 [1,2,3,4,5] == ([1,2,3],[4,5]) splitAt 1 [1,2,3] == ([1],[2,3]) splitAt 3 [1,2,3] == ([1,2,3],[]) splitAt 4 [1,2,3] == ([1,2,3],[]) splitAt 0 [1,2,3] == ([],[1,2,3]) splitAt (-1) [1,2,3] == ([],[1,2,3])It is equivalent to ( when take n xs, drop n xs)n is not _|_ (splitAt _|_ xs = _|_).
split :: (a -> Bool) -> [a] -> [[a]] Source #
Splits a list into components delimited by separators, where the predicate returns True for a separator element. The resulting components do not contain the separators. Two adjacent separators result in an empty component in the output.
split (== 'a') "aabbaca" == ["","","bb","c",""] split (== 'a') "" == [""] split (== ':') "::xyz:abc::123::" == ["","","xyz","abc","","123","",""] split (== ',') "my,list,here" == ["my","list","here"]
splitOn :: Eq a => [a] -> [a] -> [[a]] Source #
Break a list into pieces separated by the first list argument, consuming the delimiter. An empty delimiter is invalid, and will cause an error to be raised.
splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"] splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""] splitOn "x" "x" == ["",""] splitOn "x" "" == [""] \s x -> s /= "" ==> intercalate s (splitOn s x) == x \c x -> splitOn [c] x == split (==c) x
breakOn :: Eq a => [a] -> [a] -> ([a], [a]) Source #
Find the first instance of needle in haystack. The first element of the returned tuple is the prefix of haystack before needle is matched. The second is the remainder of haystack, starting with the match. If you want the remainder without the match, use stripInfix.
breakOn "::" "a::b::c" == ("a", "::b::c") breakOn "/" "foobar" == ("foobar", "") \needle haystack -> let (prefix,match) = breakOn needle haystack in prefix ++ match == haystack