LanguageExt.Core

LanguageExt.Core Immutable Collections IteratorAsync DSL

Contents

class Cons Source #

Cons iterator case.

Contains a head value and a tail that represents the rest of the sequence.

Methods

method void Deconstruct (out ValueTask<A> head, out ValueTask<IteratorAsync<A>> tail) Source #

class IteratorAsync <A> Source #

Wrapper for IEnumerator that makes it work like an immutable sequence.

It is thread-safe and impossible for any item in the sequence to be enumerated more than once.

IEnumerator from the .NET BCL has several problems:

  • It's very imperative
  • It's not thread-safe, two enumerators can't be shared

The lack of support for sharing of enumerators means that it's problematic using it internally in types like StreamT, or anything that needs to keep an IEnumerator alive for any period of time.

NOTE: There is a per-item allocation to hold the state of the iterator. These are discarded as you enumerate the sequence. However, technically it is possible to hold the initial Iterator value and subsequently gain a cached sequence of every item encountered in the enumerator.

That may well be valuable for circumstances where re-evaluation would be expensive. However, for infinite-streams this would be extremely problematic. So, make sure you discard any previous IteratorAsync values as you walk the sequence.

Parameters

type A

Item value type

class Nil Source #

Nil iterator case

The end of the sequence.

Fields

field IteratorAsync<A> Default = new Nil() Source #

Properties

property ValueTask<A> Head Source #

Head element

property ValueTask<IteratorAsync<A>> Tail Source #

Tail of the sequence

property ValueTask<bool> IsEmpty Source #

Return true if there are no elements in the sequence.

property ValueTask<long> Count Source #

Return the number of items in the sequence.

Requires all items to be evaluated, this will happen only once however.

Methods

method IteratorAsync<A> Clone () Source #

Clone the iterator so that we can consume it without having the head item referenced. This will stop any GC pressure.

method IteratorAsync<A> Split () Source #

When iterating a sequence, it is possible (before evaluation of the Tail) to Terminate the current iterator and to take a new iterator that continues on from the current location. The reasons for doing this are to break the linked-list chain so that there isn't a big linked-list of objects in memory that can't be garbage collected.

Parameters

returns

New iterator that starts from the current iterator position

method ValueTask DisposeAsync () Source #