/functional-extensions

F# inspired functional extensions for C#.

Primary LanguageC#MIT LicenseMIT

NuGet Package

Functional Extensions for C#

Some basic F# features for C#. The package fully supports C# 8.0 nullable / non-nullable reference types.

NuGet Package

PM> Install-Package AD.FunctionalExtensions -Version 2.1.0

Option

See Options in the F# docs.

var a = Option.Some(1);
var b = 1.Some();
var none = Option<int>.None;

No Null

null is treated as None.

var a = Option.Create<string>(null);

a.IsSome(); //fale
a.IsNone(); //true

Get the Value out of an Option

The only way to get the value out of an Option is in a TryGet-like manner.

var a = 1.Some();
if (a.IsSome(out var value))
{
    Console.WriteLine(value); //1
}

Compare Options

Option implements IEquatable<Option<TValue>>.

var a = 3.Some();

a.Equals(7.Some()); //false
a == 7.Some();      //false
a != 7.Some();      //true

a.Equals(3.Some()); //true
a == 3.Some();      //true
a != 3.Some();      //false

a.Equals(Option<int>.None); //false
a == Option<int>.None;      //false
a != Option<int>.None;      //true

Option implements IComparable<Option<TValue>>.

var list = new List<Option<int>>
{
    4.Some(),
    1.Some(),
    Option<int>.None,
    2.Some(),
    3.Some()
};
list.Sort();
//None
//Some(1)
//Some(2)
//Some(3)
//Some(4)

Option implements IStructuralEquatable and IStructuralComparable.

var a = "cat".Some();
var b = "CAT".Some();

a.Equals(b, StringComparer.InvariantCultureIgnoreCase); //true
a.CompareTo(b, StringComparer.InvariantCultureIgnoreCase); //0

Pattern Matching

var a = Option.Some("functional extensions for c#");

var upper = a.Match(
    onIsSome: value => value.ToUpper(),
    onIsNone: () => string.Empty);

Bind

See bind in the F# docs.

var a = Option.Some('C');

var hexDigit = a.Bind(value =>
{
    switch (value)
    {
        case 'A': return 10.Some();
        case 'B': return 11.Some();
        case 'C': return 12.Some();
        case 'D': return 13.Some();
        case 'E': return 14.Some();
        case 'F': return 15.Some();
        default: return Option<int>.None;
    }
});

Map

See map in the F# docs.

var a = Option.Some(7);

var b = a.Map(value => value * 2);

Tests

Want to see more examples? Have a look at the test code!