Mackiovello.Maybe
1.0.0
dotnet add package Mackiovello.Maybe --version 1.0.0
NuGet\Install-Package Mackiovello.Maybe -Version 1.0.0
<PackageReference Include="Mackiovello.Maybe" Version="1.0.0" />
paket add Mackiovello.Maybe --version 1.0.0
#r "nuget: Mackiovello.Maybe, 1.0.0"
// 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
Mackiovello.Maybe
Option types for C# with LINQ support and rich fluent syntax for many popular uses
Examples
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
});
Guarding
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;
try
{
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.
Lookups
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);
}
Parsing
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;
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.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 | 78,858 | 7/3/2018 |