<commit_before>Narvalo.Fx
==========

Features implementations of some of the usual suspects from functional
programming: option type (`Maybe<T>`), error types (`Result<T, TError>`,
`Outcome<T>` and `Fallible<T>`), simple disjoint union (`Either<T1, T2>`),
sequence generators and LINQ extensions.

### Status
- The next release should be the first one to be declared stable.
- Test coverage is starting to look good (75%). The number of functional tests
  is progressing too.
- C# documentation is largely missing.

### Content
- [Overview](#overview)
- [Maybe Type](#maybe-type)
- [Error Types](#error-types)
- [Either Type](#either-type)
- [LINQ Extensions](#linq-extensions)
- [Infinite Sequences](#infinite-sequences)
- [Derived API](#derived-api)
- [Design Notes](#design-notes)
- [Changelog](#changelog)

**WARNING:** _I am currently in the process of rewriting this document._

--------------------------------------------------------------------------------

Overview
--------

This assembly encourages an applicative-style of programming, or functional-style
if you prefer: types are **immutable** and methods are **pure** - they are free
of side-effects.

The main namespace is `Narvalo.Applicative`:
- `Unit`
- `Maybe<T>`, the Maybe type, a generalization of `Nullable<T>`.
- `Outcome`, an Error type with lightweight error reporting for methods without
  a return type.
- `Outcome<T>`, an Error type with lightweight error reporting.
- `Fallible`, an Error type with exception capture for methods without
  a return type.
- `Fallible<T>`, an Error type with exception capture.
- `Result<T, TError>`, the Error type.
- `Either<T1, T2>`, the Either type.
- `Sequence` which provides various ways to generate infinite sequences.
- Stubs for some commonly used delegates.

The other namespace is `Narvalo.Linq` dedicated to standard LINQ extensions.

### Remarks
Maybe, Error and Either are examples of _monads_, a concept popularized by Haskell.
If you know nothing about monads or Haskell, don't worry, no previous knowledge
is required.

The implementation of Maybe, Error and Either follows closely the Haskell API
but, of course, adapted to make more palatable to C#-developers (see
[below](#derived-api) for more details on this). These types also support the
query expression syntax [[Query expression pattern](https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#the-query-expression-pattern)].

The astute reader will have notice that some of the common monads are missing;
they were not included on purpose. In the context of C#, I am yet to be
convinced of their usefulness and practicability (for skeleton definitions of
`IO`, `Reader` and `State`,
see [here](https://github.com/chtoucas/Brouillons/tree/master/src/play/Functional/Monadic)).

--------------------------------------------------------------------------------

Maybe Type
----------

The `Maybe<T>` class is a lot like the `Nullable<T>` class but without any
restriction on the underlying type: _it provides a way to tell the absence or
the presence of a value_. For value types, most of the time `T?` offers a much
better alternative. This class is sometimes referred to as the Option type.

--------------------------------------------------------------------------------

Error Types
-----------

Typical use cases:
- To encapsulate the result of a computation with lightweight error reporting
  to the caller in the form of a string: `Outcome` and `Outcome<T>`.
- To encapsulate the result of a computation with full exception capture
  (`ExceptionDispatchInfo`): `Fallible` and `Fallible<T>`.
- In all other cases: `Result<T, TError>`.

Of course, we could have gone away with one single type, but at the expense
of complicated signatures. The correspondence is as follows:

Type             | Alternatives
-----------------|-------------
`Outcome`        | `Result<Unit, string>` or `Outcome<Unit>`
`Outcome<T>`     | `Result<T, string>`
`Fallible`       | `Result<Unit, ExceptionDispatchInfo>` or `Fallible<Unit>`
`Fallible<T>`    | `Result<T, ExceptionDispatchInfo>`

Remarks:
- All these types are value types, their primary usage is as a return type.
  For long-lived objects prefer `Either<T, TError>`.
- `Result<T, Exception>` should be used only in very rare situations; this is
  **not** a replacement for the standard exception mechanism in .NET.
  In any cases, `Fallible` and `Fallible<T>` offer better alternatives.
- You can see `Outcome` and `Outcome<T>` as verbose versions of `Maybe<Unit>`
  and `Maybe<T>`.
- **Always** prefer `Outcome` over `Maybe<TError>`.
  With `Maybe<TError>` it is not obvious that the underlying type (`TError`)
  represents an error and not the "normal" return type.

--------------------------------------------------------------------------------

Either Type
-----------

--------------------------------------------------------------------------------

LINQ Extensions
---------------

For each new query operator, we define its behaviour regarding deferred or
immediate execution. To quote the [C# documentation](https://docs.microsoft.com/en-us/dotnet/articles/csharp/programming-guide/concepts/linq/classification-of-standard-query-operators-by-manner-of-execution),
_deferred execution_ means that the operation is not performed at the point
in the code where the query is declared. Additionally,
query operators that use deferred execution can be classified as _streaming_,
they do not have to read all the source data before they yield elements,
or _not streaming_, they must read all the source data before they can yield
a result element.

### Query Operators

Category | Operator | Return Type | Deferred
-------- | -------- | ----------- | :------:
Set            | `Append`             | `IEnumerable<T>`           | Streaming
|              | `Prepend`            | `IEnumerable<T>`           | Streaming
Element        | `FirstOrNone`        | `Maybe<T>`                 | -
|              | `LastOrNone`         | `Maybe<T>`                 | -
|              | `SingleOrNone`       | `Maybe<T>`                 | -
|              | `ElementAtOrNone`    | `Maybe<T>`                 | -
Aggregation    | `Aggregate` (reduce) | `T`                        | -
|              | `Aggregate` (fold)   | `TResult` or `TAccumulate` | -
Quantification | `IsEmpty`            | `bool`                     | -
Generation     | `EmptyIfNull`        | `IEnumerable<T>`           | -

#### Set Operations
`Append` appends a new element to a sequence and `Prepend` prepends a new
element(!).

#### Element Operations
`FirstOrNone()` returns the first element of a sequence, or `Maybe<T>.None`
if the sequence contains no elements.

`FirstOrNone(predicate)` returns the first element of a sequence that satisfies the
predicate, or `Maybe<TSource>.None` if no such element is found.

`LastOrNone()` returns the last element of a sequence, or `Maybe<T>.None`
if the sequence contains no elements.

`LastOrNone(predicate)` returns the last element of a sequence that satisfies the
predicate, or `Maybe<T>.None` if no such element is found.

`SingleOrNone()` returns the only element of a sequence, or `Maybe<T>.None`
if the sequence is empty or contains more than one element. **WARNING:**
Here we differ in behaviour from the standard query `SingleOrDefault` which
throws an exception if there is more than one element in the sequence.

`SingleOrNone(predicate)` returns the only element of a sequence that satisfies
a specified predicate, or `Maybe<T>.None`
if no such element exists or there are more than one of them. **WARNING:**
Here we differ in behaviour from the standard query `SingleOrDefault` which
throws an exception if more than one element satisfies the predicate.

`ElementAtOrNone(index)` returns the element at the specified index in a
sequence or `Maybe<T>.None` if the index is out of range.

#### Aggregation Operations

#### Quantification Operations
`IsEmpty` returns true if the sequence is empty; otherwise false.

#### Generation Operations
`EmptyIfNull` returns a new empty sequence if the sequence is empty; otherwise<commit_msg>Typo.<commit_after>Narvalo.Fx
==========

Features implementations of some of the usual suspects from functional
programming: option type (`Maybe<T>`), error types (`Result<T, TError>`,
`Outcome<T>` and `Fallible<T>`), simple disjoint union (`Either<T1, T2>`),
sequence generators and LINQ extensions.

### Status
- The next release should be the first one to be declared stable.
- Test coverage is starting to look good (75%). The number of functional tests
  is progressing too.
- C# documentation is largely missing.

### Content
- [Overview](#overview)
- [Maybe Type](#maybe-type)
- [Error Types](#error-types)
- [Either Type](#either-type)
- [LINQ Extensions](#linq-extensions)
- [Infinite Sequences](#infinite-sequences)
- [Derived API](#derived-api)
- [Design Notes](#design-notes)
- [Changelog](#changelog)

**WARNING:** _I am currently in the process of rewriting this document._

--------------------------------------------------------------------------------

Overview
--------

This assembly encourages an applicative-style of programming, or functional-style
if you prefer: types are **immutable** and methods are **pure** - they are free
of side-effects.

The main namespace is `Narvalo.Applicative`:
- `Unit`
- `Maybe<T>`, the Maybe type, a generalization of `Nullable<T>`.
- `Outcome`, an Error type with lightweight error reporting for methods without
  a return type.
- `Outcome<T>`, an Error type with lightweight error reporting.
- `Fallible`, an Error type with exception capture for methods without
  a return type.
- `Fallible<T>`, an Error type with exception capture.
- `Result<T, TError>`, the Error type.
- `Either<T1, T2>`, the Either type.
- `Sequence` which provides various ways to generate infinite sequences.
- Stubs for some commonly used delegates.

The other namespace `Narvalo.Linq` is dedicated to define new (LINQ) query
operators.

### Remarks
Maybe, Error and Either are examples of _monads_, a concept popularized by Haskell.
If you know nothing about monads or Haskell, don't worry, no previous knowledge
is required.

The implementation of Maybe, Error and Either follows closely the Haskell API
but, of course, adapted to make more palatable to C#-developers (see
[below](#derived-api) for more details on this). These types also support the
query expression syntax [[Query expression pattern](https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#the-query-expression-pattern)].

The astute reader will have notice that some of the common monads are missing;
they were not included on purpose. In the context of C#, I am yet to be
convinced of their usefulness and practicability (for skeleton definitions of
`IO`, `Reader` and `State`,
see [here](https://github.com/chtoucas/Brouillons/tree/master/src/play/Functional/Monadic)).

--------------------------------------------------------------------------------

Maybe Type
----------

The `Maybe<T>` class is a lot like the `Nullable<T>` class but without any
restriction on the underlying type: _it provides a way to tell the absence or
the presence of a value_. For value types, most of the time `T?` offers a much
better alternative. This class is sometimes referred to as the Option type.

--------------------------------------------------------------------------------

Error Types
-----------

Typical use cases:
- To encapsulate the result of a computation with lightweight error reporting
  to the caller in the form of a string: `Outcome` and `Outcome<T>`.
- To encapsulate the result of a computation with full exception capture
  (`ExceptionDispatchInfo`): `Fallible` and `Fallible<T>`.
- In all other cases: `Result<T, TError>`.

Of course, we could have gone away with one single type, but at the expense
of complicated signatures. The correspondence is as follows:

Type             | Alternatives
-----------------|-------------
`Outcome`        | `Result<Unit, string>` or `Outcome<Unit>`
`Outcome<T>`     | `Result<T, string>`
`Fallible`       | `Result<Unit, ExceptionDispatchInfo>` or `Fallible<Unit>`
`Fallible<T>`    | `Result<T, ExceptionDispatchInfo>`

Remarks:
- All these types are value types, their primary usage is as a return type.
  For long-lived objects prefer `Either<T, TError>`.
- `Result<T, Exception>` should be used only in very rare situations; this is
  **not** a replacement for the standard exception mechanism in .NET.
  In any cases, `Fallible` and `Fallible<T>` offer better alternatives.
- You can see `Outcome` and `Outcome<T>` as verbose versions of `Maybe<Unit>`
  and `Maybe<T>`.
- **Always** prefer `Outcome` over `Maybe<TError>`.
  With `Maybe<TError>` it is not obvious that the underlying type (`TError`)
  represents an error and not the "normal" return type.

--------------------------------------------------------------------------------

Either Type
-----------

--------------------------------------------------------------------------------

LINQ Extensions
---------------

For each new query operator, we define its behaviour regarding deferred or
immediate execution. To quote the [C# documentation](https://docs.microsoft.com/en-us/dotnet/articles/csharp/programming-guide/concepts/linq/classification-of-standard-query-operators-by-manner-of-execution),
_deferred execution_ means that the operation is not performed at the point
in the code where the query is declared. Additionally,
query operators that use deferred execution can be classified as _streaming_,
they do not have to read all the source data before they yield elements,
or _not streaming_, they must read all the source data before they can yield
a result element.

### Query Operators

Category | Operator | Return Type | Deferred
-------- | -------- | ----------- | :------:
Set            | `Append`             | `IEnumerable<T>`           | Streaming
|              | `Prepend`            | `IEnumerable<T>`           | Streaming
Element        | `FirstOrNone`        | `Maybe<T>`                 | -
|              | `LastOrNone`         | `Maybe<T>`                 | -
|              | `SingleOrNone`       | `Maybe<T>`                 | -
|              | `ElementAtOrNone`    | `Maybe<T>`                 | -
Aggregation    | `Aggregate` (reduce) | `T`                        | -
|              | `Aggregate` (fold)   | `TResult` or `TAccumulate` | -
Quantification | `IsEmpty`            | `bool`                     | -
Generation     | `EmptyIfNull`        | `IEnumerable<T>`           | -

#### Set Operations
`Append` appends a new element to a sequence and `Prepend` prepends a new
element(!).

#### Element Operations
`FirstOrNone()` returns the first element of a sequence, or `Maybe<T>.None`
if the sequence contains no elements.

`FirstOrNone(predicate)` returns the first element of a sequence that satisfies the
predicate, or `Maybe<T>.None` if no such element is found.

`LastOrNone()` returns the last element of a sequence, or `Maybe<T>.None`
if the sequence contains no elements.

`LastOrNone(predicate)` returns the last element of a sequence that satisfies the
predicate, or `Maybe<T>.None` if no such element is found.

`SingleOrNone()` returns the only element of a sequence, or `Maybe<T>.None`
if the sequence is empty or contains more than one element. **WARNING:**
Here we differ in behaviour from the standard query `SingleOrDefault` which
throws an exception if there is more than one element in the sequence.

`SingleOrNone(predicate)` returns the only element of a sequence that satisfies
a specified predicate, or `Maybe<T>.None`
if no such element exists or there are more than one of them. **WARNING:**
Here we differ in behaviour from the standard query `SingleOrDefault` which
throws an exception if more than one element satisfies the predicate.

`ElementAtOrNone(index)` returns the element at the specified index in a
sequence or `Maybe<T>.None` if the index is out of range.

#### Aggregation Operations

#### Quantification Operations
`IsEmpty` returns true if the sequence is empty; otherwise false.

#### Generation Operations
`EmptyIfNull` returns a new empty sequence if the sequence is empty; otherwise
{'fraction_non_alphanumeric': 0.15528410142513419, 'fraction_numerical': 0.0007403294466037387, 'mean_word_length': 2.8687350835322194, 'pattern_counts': {'":': 0, '<': 95, '<?xml version=': 0, '>': 95, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '780051', 'n_tokens_mistral': 4352, 'n_tokens_neox': 4124, 'n_words': 1843}