HORIZON HASKELLDocslts/ghc-9.14.x45dd5372026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · 45dd537 · 2026-10-11

Moduleinfinite-list-0.1.3Haskell2010

Data.List.Infinite

Modern lightweight library for infinite lists with fusion:

  • API similar to Data.List.

  • No dependencies other than base.

  • Top performance, driven by fusion.

  • Avoid dangerous instances like Foldable.

  • Use NonEmpty where applicable.

  • Use Word for indices.

  • Be lazy, but not too lazy.

{-# LANGUAGE PostfixOperators #-}
import Data.List.Infinite (Infinite(..), (...), (....))
import qualified Data.List.Infinite as Inf
  • 1 type
  • 99 values

Construction

1 declaration
datadata Infinite a
#

Type of infinite lists.

In terms of recursion schemes, Infinite a is a fix point of the base functor (a,), foldr is a catamorphism and unfoldr is an anamorphism.

Constructors

Instances4Monad, Functor, MonadFix, Applicative
  • Monad InfiniteDefined in infinite-list-0.1.3 · Data.List.Infinite · orphan

    ZipList cannot be made a lawful Monad, but Infinite, being a Representable, can. Namely, join picks up a diagonal of an infinite matrix of Infinite (Infinite a). Bear in mind that this instance gets slow very soon because of linear indexing, so it is not recommended to be used in practice.

  • Functor InfiniteDefined in infinite-list-0.1.3 · Data.List.Infinite · orphan

    Just a pointwise map.

  • MonadFix InfiniteDefined in infinite-list-0.1.3 · Data.List.Infinite · orphan
  • Applicative InfiniteDefined in infinite-list-0.1.3 · Data.List.Infinite · orphan

    This instance operates pointwise, similar to ZipList.

Elimination

5 declarations
valuehead :: Infinite a -> a
#

Get the first elements of an infinite list.

valuefoldr :: (a -> b -> b) -> Infinite a -> b
#

Right-associative fold of an infinite list, necessarily lazy in the accumulator. Any unconditional attempt to force the accumulator even to the weak head normal form (WHNF) will hang the computation. E. g., the following definition isn't productive:

import Data.List.NonEmpty (NonEmpty(..))
toNonEmpty = foldr (\a (x :| xs) -> a :| x : xs) :: Infinite a -> NonEmpty a

One should use lazy patterns, e. g.,

toNonEmpty = foldr (\a ~(x :| xs) -> a :| x : xs)

This is a catamorphism on infinite lists.

Traversals

8 declarations
valuemap :: (a -> b) -> Infinite a -> Infinite b
#

Apply a function to every element of an infinite list.

valuescanl :: (b -> a -> b) -> b -> Infinite a -> Infinite b
#

Fold an infinite list from the left and return a list of successive reductions, starting from the initial accumulator:

scanl f acc (x1 :< x2 :< ...) = acc :< f acc x1 :< f (f acc x1) x2 :< ...
valuescanl1 :: (a -> a -> a) -> Infinite a -> Infinite a
#

Fold an infinite list from the left and return a list of successive reductions, starting from the first element:

scanl1 f (x0 :< x1 :< x2 :< ...) = x0 :< f x0 x1 :< f (f x0 x1) x2 :< ...
valuemapAccumL :: (acc -> x -> (acc, y)) -> acc -> Infinite x -> Infinite y
#

Fold an infinite list from the left and return a list of successive reductions, keeping accumulator in a state:

mapAccumL f acc0 (x1 :< x2 :< ...) =
  let (acc1, y1) = f acc0 x1 in
    let (acc2, y2) = f acc1 x2 in
      ...
        y1 :< y2 :< ...

If you are looking how to traverse with a state, look no further.

valuetraverse_ :: Applicative f => (a -> f ()) -> Infinite a -> f Void
#

Map each element to an action, evaluate these actions from left to right and ignore the results. Note that the return type is Void instead of usual ().

Example1 expression
traverse_ print (0...) -- hit Ctrl+C to terminate012Interrupted

traverse_ could be productive for some short-circuiting f:

Example1 expression
traverse_ (\x -> if x > 10 then Left x else Right ()) (0...)Left 11

Transformations

9 declarations
valueconcat :: Infinite (NonEmpty a) -> Infinite a
#

Flatten out an infinite list of non-empty lists.

The peculiar type with NonEmpty is to guarantee that concat is productive and results in an infinite list. Otherwise the concatenation of infinitely many [a] could still be a finite list.

valueintercalate :: NonEmpty a -> Infinite [a] -> Infinite a
#

Insert a non-empty list between adjacent elements of an infinite list, and subsequently flatten it out.

The peculiar type with NonEmpty is to guarantee that intercalate is productive and results in an infinite list. If separator is an empty list, concatenation of infinitely many [a] could still be a finite list.

valuesubsequences :: Infinite a -> Infinite [a]
#

Generate an infinite list of all finite subsequences of the argument.

Example1 expression
take 8 (subsequences (0...))[[],[0],[1],[0,1],[2],[0,2],[1,2],[0,1,2]]

Generate an infinite list of all non-empty finite subsequences of the argument.

Example1 expression
take 7 (subsequences1 (0...))[0 :| [],1 :| [],0 :| [1],2 :| [],0 :| [2],1 :| [2],0 :| [1,2]]
valuepermutations :: Infinite a -> Infinite (Infinite a)
#

Generate an infinite list of all finite (such that only finite number of elements change their positions) permutations of the argument.

Example1 expression
take 6 (fmap (take 3) (permutations (0...)))[[0,1,2],[1,0,2],[2,1,0],[1,2,0],[2,0,1],[0,2,1]]

Building

8 declarations
value(...) :: Enum a => a -> Infinite a
#

Generate an infinite progression, starting from a given element, similar to [x..]. For better user experience consider enabling {-# LANGUAGE PostfixOperators #-}:

Example2 expressions
:set -XPostfixOperatorsData.List.Infinite.take 10 (0...)[0,1,2,3,4,5,6,7,8,9]

Beware that for finite types (...) applies cycle atop of [x..]:

Example2 expressions
:set -XPostfixOperatorsData.List.Infinite.take 10 (EQ...)[EQ,GT,EQ,GT,EQ,GT,EQ,GT,EQ,GT]

Remember that Int is a finite type as well. One is unlikely to hit this on a 64-bit architecture, but on a 32-bit machine it's fairly possible to traverse ((0 :: Int) ...) far enough to encounter 0 again.

value(....) :: Enum a => (a, a) -> Infinite a
#

Generate an infinite arithmetic progression, starting from given elements, similar to [x,y..]. For better user experience consider enabling {-# LANGUAGE PostfixOperators #-}:

Example2 expressions
:set -XPostfixOperatorsData.List.Infinite.take 10 ((1,3)....)[1,3,5,7,9,11,13,15,17,19]

Beware that for finite types (....) applies cycle atop of [x,y..]:

Example2 expressions
:set -XPostfixOperatorsData.List.Infinite.take 10 ((EQ,GT)....)[EQ,GT,EQ,GT,EQ,GT,EQ,GT,EQ,GT]

Remember that Int is a finite type as well: for a sufficiently large step of progression y - x one may observe ((x :: Int, y)....) cycling back to emit x fairly soon.

valueiterate :: (a -> a) -> a -> Infinite a
#

Generate an infinite list of repeated applications.

valueunfoldr :: (b -> (a, b)) -> b -> Infinite a
#

Build an infinite list from a seed value.

This is an anamorphism on infinite lists.

valuecycle :: NonEmpty a -> Infinite a
#

Repeat a non-empty list ad infinitum. If you were looking for something like fromList :: [a] -> Infinite a, look no further.

It would be less annoying to take [a] instead of NonEmpty a, but we strive to avoid partial functions.

Sublists

14 declarations
valuedropWhile :: (a -> Bool) -> Infinite a -> Infinite a
#

Drop the longest prefix satisfying a predicate.

This function isn't productive (e. g., head . dropWhile f won't terminate), if all elements of the input list satisfy the predicate.

valuespan :: (a -> Bool) -> Infinite a -> ([a], Infinite a)
#

Split an infinite list into the longest prefix satisfying a predicate and the rest.

This function isn't productive in the second component of the tuple (e. g., head . snd . span f won't terminate), if all elements of the input list satisfy the predicate.

valuebreak :: (a -> Bool) -> Infinite a -> ([a], Infinite a)
#

Split an infinite list into the longest prefix not satisfying a predicate and the rest.

This function isn't productive in the second component of the tuple (e. g., head . snd . break f won't terminate), if no elements of the input list satisfy the predicate.

valueinits :: Infinite a -> Infinite [a]
#

Generate all prefixes of an infinite list.

Example2 expressions
:set -XPostfixOperatorsData.List.Infinite.take 5 $ Data.List.Infinite.inits (0...)[[],[0],[0,1],[0,1,2],[0,1,2,3]]

If you need reversed prefixes, they can be generated cheaper using scanl':

Example2 expressions
:set -XPostfixOperatorsData.List.Infinite.take 5 $ Data.List.Infinite.scanl' (flip (:)) [] (0...)[[],[0],[1,0],[2,1,0],[3,2,1,0]]

Searching

8 declarations
valuefilter :: (a -> Bool) -> Infinite a -> Infinite a
#

Filter an infinite list, removing elements which does not satisfy a predicate.

This function isn't productive (e. g., head . filter f won't terminate), if no elements of the input list satisfy the predicate.

A common objection is that since it could happen that no elements of the input satisfy the predicate, the return type should be [a] instead of Infinite a. This would not however make filter any more productive. Note that such hypothetical filter could not ever generate [] constructor, only (:), so we would just have a more lax type gaining nothing instead. Same reasoning applies to other filtering / partitioning / searching functions.

valuelookup :: Eq a => a -> Infinite (a, b) -> b
#

Find the first pair, whose first component is equal to the first argument, and return the second component. If there is nothing to be found, this function will hang indefinitely.

valuefind :: (a -> Bool) -> Infinite a -> a
#

Find the first element, satisfying a predicate. If there is nothing to be found, this function will hang indefinitely.

valuemapMaybe :: (a -> Maybe b) -> Infinite a -> Infinite b
#

Apply a function to every element of an infinite list and collect Just results.

This function isn't productive (e. g., head . mapMaybe f won't terminate), if no elements of the input list result in Just.

valuepartition :: (a -> Bool) -> Infinite a -> (Infinite a, Infinite a)
#

Split an infinite list into two infinite lists: the first one contains elements, satisfying a predicate, and the second one the rest.

This function isn't productive in the first component of the tuple (e. g., head . fst . partition f won't terminate), if no elements of the input list satisfy the predicate. Same for the second component, if all elements of the input list satisfy the predicate.

Indexing

5 declarations
value(!!) :: Infinite a -> Word -> a
#

Return n-th element of an infinite list. On contrary to Data.List.!!, this function takes Word instead of Int to avoid error on negative arguments.

If you are concerned that unsigned indices may accidentally underflow, compile with -fno-ignore-asserts: there is an assert checking that the index does not exceed fromIntegral (maxBound :: Int).

This is actually index from Representable type class in disguise.

valueelemIndex :: Eq a => a -> Infinite a -> Word
#

Return an index of the first element, equal to a given. If there is nothing to be found, this function will hang indefinitely.

valueelemIndices :: Eq a => a -> Infinite a -> Infinite Word
#

Return indices of all elements, equal to a given.

This function isn't productive (e. g., head . elemIndices f won't terminate), if no elements of the input list are equal the given one.

valuefindIndex :: (a -> Bool) -> Infinite a -> Word
#

Return an index of the first element, satisfying a predicate. If there is nothing to be found, this function will hang indefinitely.

Zipping

20 declarations
valueheteroZip :: Traversable t => Infinite a -> t b -> t (a, b)
#

Zip an Infinite with any Traversable, maintaining the shape of the latter.

Example2 expressions
import Data.Functor.Compose (Compose(..))heteroZip (0...) (Compose [Just 10, Nothing, Just 20])Compose [Just (0,10),Nothing,Just (1,20)]
valueheteroZipWith :: Traversable t => (a -> b -> c) -> Infinite a -> t b -> t c
#

Use a given function to zip an Infinite with any Traversable, maintaining the shape of the latter.

Example2 expressions
import Data.Functor.Compose (Compose(..))heteroZipWith (+) (0...) (Compose [Just 10, Nothing, Just 20])Compose [Just 10,Nothing,Just 21]

Functions on strings

4 declarations

Split an infinite string into words, by any isSpace symbol. Leading spaces are removed and, as underlined by the return type, repeated spaces are treated as a single delimiter.

Set operations

6 declarations
valuenub :: Eq a => Infinite a -> Infinite a
#

Remove duplicate from a list, keeping only the first occurrence of each element. Because of a very weak constraint on a, this operation takes O(n²) time. Consider using nubOrd instead.

value(\\) :: Eq a => Infinite a -> [a] -> Infinite a
#

Take an infinite list and remove the first occurrence of every element of a finite list.

valueunion :: Eq a => [a] -> Infinite a -> Infinite a
#

Union of a finite and an infinite list. It contains the finite list as a prefix and afterwards all non-duplicate elements of the infinite list, which are not members of the finite list.

valueintersect :: Eq a => Infinite a -> [a] -> Infinite a
#

Return all elements of an infinite list, which are simultaneously members of a finite list.

Ordered lists

1 declaration
valueinsert :: Ord a => a -> Infinite a -> Infinite a
#

Insert an element at the first position where it is less than or equal to the next one. If the input was sorted, the output remains sorted as well.

Generalized functions

11 declarations

Orphan instances

4 instances