HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

  • PackageAgda-2.7.0.1
  • Exports74
  • LanguageHaskell2010
  • LicenceMIT
  • SourceList.hs

Variants of list case, cons, head, tail, init, last

19 declarations
valuesnoc :: [a] -> a -> [a]
#

Append a single element at the end. Time: O(length); use only on small lists.

valuecaseList :: [a] -> b -> (a -> [a] -> b) -> b
#

Case distinction for lists, with list first. O(1).

Cf. ifNull.

valuecaseListM :: Monad m => m [a] -> m b -> (a -> [a] -> m b) -> m b
#

Case distinction for lists, with list first. O(1).

Cf. ifNull.

valuelistCase :: b -> (a -> [a] -> b) -> [a] -> b
#

Case distinction for lists, with list last. O(1).

valueheadWithDefault :: a -> [a] -> a
#

Head function (safe). Returns a default value on empty lists. O(1).

headWithDefault 42 []      = 42
headWithDefault 42 [1,2,3] = 1
valuetailWithDefault :: [a] -> [a] -> [a]
#

Tail function (safe). Returns a default list on empty lists. O(1).

valuelastWithDefault :: a -> [a] -> a
#

Last element (safe). Returns a default list on empty lists. O(n).

valuelast1 :: a -> [a] -> a
#

Last element of non-empty list (safe). O(n). last1 a as = last (a : as)

valuelast2 :: [a] -> Maybe (a, a)
#

Last two elements (safe). O(n).

valuelast2' :: a -> a -> [a] -> (a, a)
#

last2' x y zs computes the last two elements of x:y:zs. O(n).

valueuncons :: [a] -> Maybe (a, [a])
#

Opposite of cons (:), safe. O(1).

valuemcons :: Maybe a -> [a] -> [a]
#

Maybe cons. O(1). mcons ma as = maybeToList ma ++ as

valueinitLast1 :: a -> [a] -> ([a], a)
#

init and last of non-empty list, safe. O(n). initLast1 a as = (init (a:as), last (a:as)

valueinit1 :: a -> [a] -> [a]
#

init of non-empty list, safe. O(n). init1 a as = init (a:as)

Lookup and indexing

6 declarations
value(!!!) :: [a] -> Int -> Maybe a
#

Lookup function (safe). O(min n index).

value(!!) :: HasCallStack => [a] -> Int -> a
#

A variant of !! that might provide more informative error messages if the index is out of bounds.

Precondition: The index should not be out of bounds.

valueindexWithDefault :: a -> [a] -> Int -> a
#

Lookup function with default value for index out of range. O(min n index).

The name is chosen akin to genericIndex.

valuefindWithIndex :: (a -> Bool) -> [a] -> Maybe (a, Int)
#

Find an element satisfying a predicate and return it with its index. O(n) in the worst case, e.g. findWithIndex f xs = Nothing.

TODO: more efficient implementation!?

Update

3 declarations
valueupdateHead :: (a -> a) -> [a] -> [a]
#

Update the first element of a list, if it exists. O(1).

valueupdateLast :: (a -> a) -> [a] -> [a]
#

Update the last element of a list, if it exists. O(n).

valueupdateAt :: Int -> (a -> a) -> [a] -> [a]
#

Update nth element of a list, if it exists. O(min index n).

Precondition: the index is >= 0.

Sublist extraction and partitioning

15 declarations
valuedropEnd :: Int -> [a] -> Prefix a
#

Drop from the end of a list. O(length).

dropEnd n = reverse . drop n . reverse

Forces the whole list even for n==0.

valuespanEnd :: (a -> Bool) -> [a] -> (Prefix a, Suffix a)
#

Split off the largest suffix whose elements satisfy a predicate. O(n).

spanEnd p xs = (ys, zs) where xs = ys ++ zs and all p zs and maybe True (not . p) (lastMaybe yz).

valuebreakAfter1 :: (a -> Bool) -> a -> [a] -> (List1 a, [a])
#

Breaks a list just after an element satisfying the predicate is found.

Example1 expression
breakAfter1 even 1 [3,5,2,4,7,8](1 :| [3,5,2],[4,7,8])
valuebreakAfter :: (a -> Bool) -> [a] -> ([a], [a])
#

Breaks a list just after an element satisfying the predicate is found.

Example1 expression
breakAfter even [1,3,5,2,4,7,8]([1,3,5,2],[4,7,8])
valuetakeWhileJust :: (a -> Maybe b) -> [a] -> Prefix b
#

A generalized version of takeWhile. (Cf. mapMaybe vs. filter). @O(length . takeWhileJust f).

takeWhileJust f = fst . spanJust f.

valuepartitionMaybe :: (a -> Maybe b) -> [a] -> ([a], [b])
#

Partition a list into Nothings and Justs. O(n).

partitionMaybe f = partitionEithers . map ( a -> maybe (Left a) Right (f a))

Note: mapMaybe f = snd . partitionMaybe f.

valuefilterAndRest :: (a -> Bool) -> [a] -> ([a], Suffix a)
#

Like filter, but additionally return the last partition of the list where the predicate is False everywhere. O(n).

valuemapMaybeAndRest :: (a -> Maybe b) -> [a] -> ([b], Suffix a)
#

Like mapMaybe, but additionally return the last partition of the list where the function always returns Nothing. O(n).

valuedropFrom :: Eq a => List1 a -> [a] -> [a]
#

dropFrom marker xs drops everything from xs starting with (and including) marker.

If the marker does not appear, the string is returned unchanged.

The following two properties hold provided marker has no overlap with xs:

  dropFrom marker (xs ++ marker ++ ys) == xs
  dropFrom marker xs == xs
valueholes :: [a] -> [(a, [a])]
#

All ways of removing one element from a list. O(n²).

Prefix and suffix

0 declarations

Prefix

valuecommonPrefix :: Eq a => [a] -> [a] -> Prefix a
#

Compute the common prefix of two lists. O(min n m).

valuedropCommon :: [a] -> [b] -> (Suffix a, Suffix b)
#

Drops from both lists simultaneously until one list is empty. O(min n m).

valuestripPrefixBy :: (a -> a -> Bool) -> Prefix a -> [a] -> Maybe (Suffix a)
#

Check if a list has a given prefix. If so, return the list minus the prefix. O(length prefix).

Suffix

valuecommonSuffix :: Eq a => [a] -> [a] -> Suffix a
#

Compute the common suffix of two lists. O(n + m).

valuesuffixesSatisfying :: (a -> Bool) -> [a] -> [Bool]
#

Returns a list with one boolean for each non-empty suffix of the list, starting with the longest suffix (the entire list). Each boolean is True exactly when every element in the corresponding suffix satisfies the predicate.

An example: suffixesSatisfying isLower AbCde = [False, False, False, True, True]

For total predicates p and finite and total lists xs the following holds: suffixesSatisfying p xs = map (all p) (init (tails xs))

Finding overlap

valuefindOverlap :: Eq a => [a] -> [a] -> (Int, Int)
#

Find the longest suffix of the first string xs that is a prefix of the second string ys. So, basically, find the overlap where the strings can be glued together. Returns the index where the overlap starts and the length of the overlap. The length of the overlap plus the index is the length of the first string. Note that in the worst case, the empty overlap (length xs,0) is returned.

Worst-case time complexity is quadratic: O(min(n,m)²) where n = length xs and m = length ys.

There might be asymptotically better implementations following Knuth-Morris-Pratt (KMP), but for rather short lists this is good enough.

Chunks

2 declarations
valuechop :: Int -> [a] -> [[a]]
#

Chop up a list in chunks of a given length. O(n).

valuechopWhen :: (a -> Bool) -> [a] -> [[a]]
#

Chop a list at the positions when the predicate holds. Contrary to wordsBy, consecutive separator elements will result in an empty segment in the result. O(n).

intercalate [x] (chopWhen (== x) xs) == xs

List as sets

13 declarations
valuehasElem :: Ord a => [a] -> a -> Bool
#

Check membership for the same list often. Use partially applied to create membership predicate hasElem xs :: a -> Bool.

  • First time: O(n log n) in the worst case.

  • Subsequently: O(log n).

Specification: hasElem xs == (elem xs).

valuesorted :: Ord a => [a] -> Bool
#

Check whether a list is sorted. O(n).

Assumes that the Ord instance implements a partial order.

valueallConsecutive :: (a -> a -> Bool) -> [a] -> Bool
#

Check whether all consecutive elements of a list satisfy the given relation. O(n).

valuedistinct :: Eq a => [a] -> Bool
#

Check whether all elements in a list are distinct from each other. Assumes that the Eq instance stands for an equivalence relation.

O(n²) in the worst case distinct xs == True.

valueduplicates :: Ord a => [a] -> [a]
#

Returns an (arbitrary) representative for each list element that occurs more than once. O(n log n).

valueallDuplicates :: Ord a => [a] -> [a]
#

Remove the first representative for each list element. Thus, returns all duplicate copies. O(n log n).

allDuplicates xs == sort $ xs \ nub xs.

valuenubAndDuplicatesOn :: Ord b => (a -> b) -> [a] -> ([a], [a])
#

Partition a list into first and later occurrences of elements (modulo some quotient given by a representation function).

Time: O(n log n).

Specification:

nubAndDuplicatesOn f xs = (ys, xs List.\\ ys)
  where ys = nubOn f xs
valuenubOn :: Ord b => (a -> b) -> [a] -> [a]
#

Efficient variant of nubBy for lists, using a set to store already seen elements. O(n log n)

Specification:

nubOn f xs == 'nubBy' ((==) `'on'` f) xs.
valuenubFavouriteOn
  1. :: (Ord b, Eq c, Hashable c)
  2. => (a -> b)

    The values returned by this function are used to determine which element from a group of equal elements that is returned: the smallest one is chosen (and if two elements are equally small, then the first one is chosen).

  3. -> (a -> c)

    Two elements are treated as equal if this function returns the same value for both elements.

  4. -> [a]
  5. -> [a]
#

A variant of nubOn that is parametrised by a function that is used to select which element from a group of equal elements that is returned. The returned elements keep the order that they had in the input list.

Precondition: The length of the input list must be at most maxBound :: Int.

valueuniqOn :: Ord b => (a -> b) -> [a] -> [a]
#

Efficient variant of nubBy for finite lists. O(n log n).

uniqOn f == 'List.sortBy' (compare `'on'` f) . 'nubBy' ((==) `'on'` f)

If there are several elements with the same f-representative, the first of these is kept.

valueallEqual :: Eq a => [a] -> Bool
#

Checks if all the elements in the list are equal. Assumes that the Eq instance stands for an equivalence relation. O(n).

valuenubM :: Monad m => (a -> a -> m Bool) -> [a] -> m [a]
#

Non-efficient, monadic nub. O(n²).

Zipping

2 declarations
valuezipWith' :: (a -> b -> c) -> [a] -> [b] -> Maybe [c]
#

Requires both lists to have the same length. O(n).

Otherwise, Nothing is returned.

valuezipWithKeepRest :: (a -> b -> b) -> [a] -> [b] -> [b]
#

Like zipWith but keep the rest of the second list as-is (in case the second list is longer). O(n).

  zipWithKeepRest f as bs == zipWith f as bs ++ drop (length as) bs

Unzipping

1 declaration
valueunzipWith :: (a -> (b, c)) -> [a] -> ([b], [c])
#

Edit distance

3 declarations
valueeditDistanceSpec :: Eq a => [a] -> [a] -> Int
#

Implemented using tree recursion, don't run me at home! O(3^(min n m)).

valueeditDistance :: Eq a => [a] -> [a] -> Int
#

Implemented using dynamic programming and Data.Array. O(n*m).