PowMaybe 0.1.0

dotnet add package PowMaybe --version 0.1.0                
NuGet\Install-Package PowMaybe -Version 0.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PowMaybe" Version="0.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add PowMaybe --version 0.1.0                
#r "nuget: PowMaybe, 0.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install PowMaybe as a Cake Addin
#addin nuget:?package=PowMaybe&version=0.1.0

// Install PowMaybe as a Cake Tool
#tool nuget:?package=PowMaybe&version=0.1.0                

PowMaybe

Table of content

Introduction

Lightweight Maybe monad library to simplify code that can fail.

It will help you transform code like this:

Before

Person? ParsePage(string url)
{
    var html = client.Query(url);
    if (html == null)
        return null;
    var root = Html.GetRoot(html);
    var node = root.SelectSingleNode("xpath query");
    if (node == null)
        return null;
    var personInfo = Utils.ParseNode(node);
    if (personInfo == null)
        return null;
    return new Person(personInfo);
}

Into this:

After

Maybe<Person> ParsePage(string url) =>
    from html in Utils.Query(url)
    let root = Utils.GetRoot(html)
    from node in root.MaySelectSingleNode("xpath query")
    from personInfo in Utils.MayParseNode(node)
    select new Person(personInfo);

The result is:

  • shorter code
  • less nested
  • no if conditions
  • no nullable references

It will not apply for all the code everywhere, but when it does apply it will drastically reduce the potential for bugs.

Usage

Creation

var a = May.Some(47);
var b = May.None<string>();
// nullable reference -> Maybe<>
var mayPerson = person.ToMaybe();
// Maybe<> -> nullable reference
var person = mayPerson.ToNullable();

Combining

Maybe<string> QueryHtml(string url);
Maybe<Person> ParsePerson(string html);

// use any number of from/in statements with a select at the end
Maybe<Person> QueryAndParse(string url) =>
    from html in QueryHtml(url)
    from person in ParsePerson(html)
    where person.Name != "John" // you can also use where statements
    select parson;

Unwrapping

Maybe<Person> mayPerson = ...

if (mayPerson.IsSome(out var person))
{
    // Success, you can access person here
}
else
{
    // Failure
}

Person person = mayPerson.Ensure(); // throws an Exception if mayPerson is None

Person person = mayPerson.FailWith(peter); // returns peter if mayPerson is None

Enumerations

IEnumerable<T> WhereSome<T>(this IEnumerable<Maybe<T>> source);
Maybe<T> FirstOrMaybe<T>(this IEnumerable<T> source, Func<T, bool>? predicate = null)
// and similar LastOrMaybe

// Examples
// ========
new [] { May.Some(4), May.None<int>() May.Some(12) }.WhereSome();
// int[] { 4, 12 }

new [] { 2, 6, 5 }.FirstOrMaybe(e => e % 3 == 0)
// Some(6)

new [] { 2, 6, 5 }.FirstOrMaybe(e => e % 3 == 1)
// None<int>()

Example

Let's say you want to read your configuration from multiple sources:

  • environment variables
  • command line arguments
  • json file

And once a source returns a configuration, you do not want to read the other sources.

You could write it this way:

Maybe<Config> ReadFromEnvVars();
Maybe<Config> ReadFromArgs(string[] args);
Maybe<Config> ReadFromFile(string file);

Maybe<Config> ReadConfig(string[] args, string file) =>
	new[]
	{
		() => ReadFromEnvVars(),
		() => ReadFromArgs(args),
		() => ReadFromFile(file),
	}
	.Select(readFun => readFun())
	.WhereSome()
	.FirstOrMaybe();

License

MIT

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on PowMaybe:

Package Downloads
PowRxVar.Maybe

Composable reactive variables

PowRxVar.WinForms

Composable reactive variables

PowWeb

Puppeteer and Chrome DOMSnapshot API wrapper

ImdbLib

IMDB scraping

ParserLib

Parsing utilities

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.0 102 6/30/2024
0.0.12 233 8/9/2023
0.0.11 479 6/12/2023
0.0.10 221 6/5/2023
0.0.9 441 5/28/2023
0.0.7 165 4/30/2023
0.0.6 510 11/26/2022
0.0.5 316 11/26/2022
0.0.4 544 11/15/2022
0.0.2 376 8/13/2022
0.0.1 334 8/13/2022