Mackiovello.Maybe 1.0.0

Install-Package Mackiovello.Maybe -Version 1.0.0
dotnet add package Mackiovello.Maybe --version 1.0.0
<PackageReference Include="Mackiovello.Maybe" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Mackiovello.Maybe --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Mackiovello.Maybe, 1.0.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Mackiovello.Maybe as a Cake Addin
#addin nuget:?package=Mackiovello.Maybe&version=1.0.0

// Install Mackiovello.Maybe as a Cake Tool
#tool nuget:?package=Mackiovello.Maybe&version=1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.


Build Status

Option types for C# with LINQ support and rich fluent syntax for many popular uses


All these examples require that you have the following using statement:

using Mackiovello.Maybe

Computing on maybe types

Maybe<string> maybeGood = "hello".ToMaybe();
Maybe<string> maybeJunk = Maybe<string>.Nothing;

var concat = from good in maybeGood
             from junk in maybeJunk
             select good + junk;

if (concat.IsNothing())
  Console.WriteLine("One of the strings was bad, could not concat");

LINQ terminates the computation if there's a Nothing at any point in the computation.

Running a computation with a maybe type:

string nullString = null;

nullString.ToMaybe().Do(str => 
  // str will never be null, ToMaybe guards against null and Do unwraps the value


You can check a condition on a maybe type and guard against them:

string name = "Bill Casarin";
Maybe<string> maybeName = from n in name.ToMaybe()
                          where n.StartsWith("Bill")
                          select n;

If the name didn't start with Bill, maybeName would be Maybe<string>.Nothing

Maybe coalescing

Maybe has an operator similar to the null coalescing operator ??. We achieve optional short-circuit evaluation with lambdas:

Maybe<string> name1 = Maybe<string>.Nothing;
Maybe<string> name2 = "Some Name".ToMaybe();

Maybe<string> goodNameLazy = name1.Or(() => name2);
// this works too:
Maybe<string> goodName = name1.Or(name2);
// and this:
Maybe<string> goodName = name1.Or("goodName");

You can also convert value-kinded maybe types to Nullable<T>s:

Maybe<int> maybeNumber = Maybe<int>.Nothing;
Maybe<int> maybeAnotherNumber = (4).ToMaybe();

int? ok = maybeNumber.ToNullable() ?? maybeAnotherNumber.ToNullable();

Extracting values

Sometime you want to pull out a value with a default value in case of Nothing:

Maybe<string> possibleString = Maybe<string>.Nothing;
string goodString = possibleString.OrElse("default");

The default parameter can also be lazy:

string goodString = possibleString.OrElse(() => doHeavyComputationForString());

Or you can throw an exception instead:

string val = null;
  val = (Maybe<string>.Nothing).OrElse(() => new Exception("no value"));
catch (Exception) 
  // exception will be thrown

Or, finally, you can just get the default value for that type:

string val = maybeString.OrElseDefault();

Why not use Nullable<T> instead?

Nullable<T> only works on value types. Maybe<T> works on both value and reference types. It also has LINQ support.

More interesting examples

Getting the first element of a list

public static Maybe<T> Head<T>(this IEnumerable<T> xs) 
  foreach(var x in xs)
    return x.ToMaybe();
  return Maybe<T>.Nothing;

Now lets get a bunch of heads!

var result = from h1 in list1.Head()
             from h2 in list2.Head()
             from h3 in list3.Head()
             select ConsumeHeads(h1, h2, h3);

ConsumeHeads will never run unless all Head() calls return valid results.


Here's a function for getting a value out of a dictionary:

public static Maybe<T2> Lookup<T, T2>(this IDictionary<T, T2> d, T key) 
  var getter = MaybeFunctionalWrappers.Wrap(d.TryGetValue);
  return getter(key);


public static Maybe<int> ParseInt(string s) 
  var parser = MaybeFunctionalWrappers.Wrap(int.TryParse);
  return parser(s);

Lookup + Parsing!

var parsedFromDict = from val in d.Lookup("key")
                     from parsedVal in ParseInt(val)
                     select parsedVal;
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 49,507 7/3/2018