HORIZON HASKELLDocslts/ghc-10.0.x8fef28d2026-11-02Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8fef28d · 2026-11-02

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
Contents
  1. Construction
  2. Elimination
  3. Traversals
  4. Transformations
  5. Building
  6. Sublists
  7. Searching
  8. Indexing
  9. Zipping
  10. Functions on strings
  11. Set operations
  12. Ordered lists
  13. Generalized functions
Synopsis

Construction

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

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

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

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]]

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

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.

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

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

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.

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

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.

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

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

Set operations

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.

Ordered lists

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

Orphan instances

4 instances