• Stars
    star
    24
  • Rank 952,650 (Top 20 %)
  • Language
    C#
  • License
    Apache License 2.0
  • Created over 5 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

.NET Standard Library for giving (bool, T) Option-like semantics

Optuple

Optuple is a .NET Standard library that enables a tuple of Boolean and some type (T), i.e. (bool, T), to have the same semantics as an option type found in most functional languages.

An option type is a discriminated union that either represents the absence of a value (none) or the value that's present (some). For example, F# has such a type that is defined as:

type Option<T> = | None | Some of T

Optuple, however, does not define any such type. Instead it primarily supplies extension methods for any (bool, T) (like Match, Map and more) to be treated like an option type. Suppose a value x of type T, then (true, x) will be treated like Some x and (false, _) will be treated like None. Note that in the none case, when the first element is false, Optuple completely ignores and discards the second element.

A library that wants to expose optional values needs no dependency on Optuple. It can just expose (bool, T) for some type T. The client of the library can use Optuple independently to get “optional semantics”.

Usage

Using the library

To use Optuple simply import the following namespace:

using Optuple;

An auxiliary namespace is also provided:

using Optuple.Linq; // LINQ query syntax support

Creating optional values

The most basic way to create optional values is to use the static Option class:

var none = Option.None<int>();
var some = Option.Some(42);

Similarly, a more general extension method is provided, allowing a specified predicate:

string str = "foo";
var none = Option.SomeWhen(str, s => s == "bar"); // Return None if predicate is violated
var none = Option.NoneWhen(str, s => s == "foo"); // Return None if predicate is satisfied

Clearly, optional values are conceptually quite similar to nullables. Hence, a method is provided to convert a nullable into an optional value:

int? nullableWithoutValue = null;
int? nullableWithValue = 2;
var none = nullableWithoutValue.ToOption();
var some = nullableWithValue.ToOption();

Retrieving values

When retrieving values, Optuple forces you to consider both cases (that is if a value is present or not).

Firstly, it is possible to check if a value is actually present:

var isSome = option.IsSome(); //returns true if a value is present
var isNone = option.IsNone(); //returns true if a value is not present

If you want to check if an option option satisfies some predicate, you can use theExists method.

var isGreaterThanHundred = option.Exists(val => val > 100);

The most basic way to retrieve a value from an Option<T> is the following:

// Returns the value if present, or otherwise an alternative value (42)
var value = option.Or(42);

Similarly, the OrDefault function simply retrieves the default value for a given type:

var none = Option.None<int>();
var value = none.OrDefault(); // Value 0
var none = Option.None<string>();
var value = none.OrDefault(); // null

In more elaborate scenarios, the Match method evaluates a specified function:

// Evaluates one of the provided functions and returns the result
var value = option.Match(x => x + 1, () => 42);

// Or written in a more functional style (pattern matching)
var value = option.Match(
  some: x => x + 1,
  none: () => 42
);

There is a similar Match function to simply induce side-effects:

// Evaluates one of the provided actions
option.Match(x => Console.WriteLine(x), () => Console.WriteLine(42));

// Or pattern matching style as before
option.Match(
  some: x => Console.WriteLine(x),
  none: () => Console.WriteLine(42)
);

Transforming and filtering values

A few extension methods are provided to safely manipulate optional values.

The Map function transforms the inner value of an option. If no value is present none is simply propagated:

var none = Option.None<int>();
var stillNone = none.Map(x => x + 10);

var some = Option.Some(42);
var somePlus10 = some.Map(x => x + 10);

Finally, it is possible to perform filtering. The Filter function returns none, if the specified predicate is not satisfied. If the option is already none, it is simply returned as is:

var none = Option.None<int>();
var stillNone = none.Filter(x => x > 10);

var some = Option.Some(10);
var stillSome = some.Filter(x => x == 10);
var none = some.Filter(x => x != 10);

Helpers as global methods

If you statically import OptionModule:

using static Optuple.OptionModule;

it will make the following common methods available for use without type qualification:

  • Some
  • None<>
  • SomeWhen
  • NoneWhen

This permits you to, for example, simply write Some(42) and None<int>() instead of Option.Some(42) and None<int>(), respectively.

Enumerating options

Although options deliberately don't act as enumerables, you can easily convert an option to an enumerable by calling the ToEnumerable() method:

var enumerable = option.ToEnumerable();

By importing the Optuple.Collections namespace, you also get the following extension methods for sequences (IEnumerable<>) that are like their LINQ counterparts but return an option:

Then there is:

  • Filter, which given a sequence of options, will return a sequence of x values from those options in the original sequence that are some x.
  • ListAll, which given a sequence of options, will return some list of x if all options in the original sequence are some x; otherwise it returns none list.

Working with LINQ query syntax

Optuple supports LINQ query syntax, to make the above transformations somewhat cleaner.

To use LINQ query syntax you must import the following namespace:

using Optuple.Linq;

This allows you to do fancy stuff such as:

var personWithGreenHair =
  from person in FindPersonById(10)
  from hairstyle in GetHairstyle(person)
  from color in ParseStringToColor("green")
  where hairstyle.Color == color
  select person;

In general, this closely resembles a sequence of calls to FlatMap and Filter. However, using query syntax can be a lot easier to read in complex cases.

Equivalence and comparison

Two optional values are equal if the following is satisfied:

  • The two options have the same type
  • Both are none, both contain null values, or the contained values are equal

Credit: A large portion of this documentation was dervied from that of the project Optional. Thank you, Nils Lück!

More Repositories

1

NCrontab

Crontab for .NET
C#
823
star
2

LinqPadless

LINQPad Queries without LINQPad
C#
268
star
3

Fizzler

.NET CSS Selector Engine
C#
120
star
4

High5

HTML parsing & serialization toolset for .NET Standard
HTML
100
star
5

t5

T5 is T4 (Text Template Transformation Toolkit) for .NET Core
C#
75
star
6

JSONPath

JSONPath (XPath-like syntax for JSON) C# implementation
C#
71
star
7

Hazz

CSS Selectors (via Fizzler) for HtmlAgilityPack (HAP)
C#
57
star
8

StackTraceParser

C# parser for .NET & Mono stack traces
C#
54
star
9

CSharpMinifier

.NET Standard Library & Tool for C# source code minification
C#
33
star
10

Transplator

Simple C# source generator for text templates
C#
26
star
11

WebLinq

LINQ to Web or teaching LINQ to do Web so the Web appears like simple LINQ queries
C#
24
star
12

StackTraceFormatter

C# formatter for .NET & Mono stack traces
C#
23
star
13

Jayrock

JSON & JSON-RPC for .NET Framework & Mono
C#
22
star
14

FakeLinqPad

Fake replacement for LINQPad API
C#
16
star
15

Dsv

.NET Standard Library for Parsing DSV (Delimiter-Separated Values) data like CSV
C#
14
star
16

Escape

JavaScript parser for .NET Standard based on the Esprima code base
JavaScript
12
star
17

LINQBridge

Re-implementation of LINQ to Objects for .NET Framework 2.0
C#
12
star
18

TryParsers

TryParse methods done right for .NET Standard
C#
10
star
19

Jacob

A succinct and compositional .NET API for reading JSON
C#
8
star
20

Gini

INI File Format Parser
C#
7
star
21

CSharpMinifierDemo

Single-Page Application based on Blazor (WebAssembly) demonstrating CSharpMinifier in action
CSS
6
star
22

AngryArrays

Extension methods for transforming arrays
C#
6
star
23

CSharpSyntaxValidator

.NET Core tool to validate C# source syntax
C#
6
star
24

Nunycode

Punycode for .NET derived from https://mths.be/punycode
C#
6
star
25

SplitCsvApp

CSV Splitter Utility
C#
5
star
26

NDate

Date (without Time) for .NET
C#
4
star
27

A1

Column-Row with A1-style parsing & formatting
C#
4
star
28

Spawnr

System.Diagnostics.Process.Start Made Simple
C#
3
star
29

Boxing

.NET Standard library for boxing any value
C#
3
star
30

windu

Disk usage database utility written in C#; that is ⚠ not actively maintained!
C#
3
star
31

LinqPadCsvFix

Fix CSV Output of LINQPad Reactive Queries
C#
3
star
32

Crockbase32

C# implementation of Douglas Crockford's Base 32
C#
3
star
33

Gratt

A Generic Vaughn Pratt's top-down operator precedence parser for .NET Standard
C#
3
star
34

Rejex

Regex à la LINQ 🚧
C#
3
star
35

XlTableFormat

XlTable format reader
C#
3
star
36

KeyValuePairs

.NET Standard library with helper and extension methods that exclusively deal with KeyValuePair<,>
C#
3
star
37

dyndlg

Dynamic Dialog Boxes for Windows
C
2
star
38

findpath

Console tool to find a file on the standard Windows search path
C++
2
star
39

Interlocker

Interlocked.CompareExchange boilerplate
C#
2
star
40

TextDataReader

An IDataReader implementation for text sources
C#
2
star
41

Worms

Awaitable Synchronization Primitives Library for .NET
C#
2
star
42

BasicTextFieldParser

Visual Basic's TextFieldParser for .NET Standard
C#
1
star
43

wshgrep

Grep-like using Windows Script Host
JavaScript
1
star
44

VisualFizzler

WinForms Application for visualising CSS Selectors
C#
1
star
45

elvee

Small cross-platform shim in C to run the latest version of an executable
C
1
star
46

cmdqp.cmd

Windows Command Queue Processor Scripts
Batchfile
1
star
47

Delegating.AspNet

.NET Library providing delegated implementations of common ASP.NET interfaces
C#
1
star
48

Builders

This project is work in progress 🚧
C#
1
star
49

Gist

My Gists
JavaScript
1
star
50

Kons

Simple Cons List for .NET
C#
1
star
51

Jayrock.Json

.NET Standard Library for reading and writing JSON
C#
1
star
52

secrets.ps

PowerShell scripts to protect secrets in files via Windows DPAPI (Data Protection API)
PowerShell
1
star
53

recolor

.NET Core Tool that colors regex matches on STDIN lines
C#
1
star
54

JsonChecker

http://www.raboof.com/projects/jsonchecker/
C#
1
star
55

OpenWebClient

An “open” subclass of System.Net.WebClient
C#
1
star
56

pie.ps

Pie = Python installer extraordinaire! A PowerShell script for isolated installation of a project's required versions of Python, pip & packages
PowerShell
1
star
57

WebLinqExamples

Examples of scrapes using WebLINQ
1
star
58

sstart.vbs

WSH script to launch a program without any visible user interface
Visual Basic
1
star
59

Jazmin

.NET Global Tool to filter comments & unnecessary whitespace from JavaScript
C#
1
star
60

Eggado

ADO.NET modernizer
C#
1
star
61

NotWebMatrix.Data

Open source clone of mostly WebMatrix.Data and then some more
C#
1
star
62

Choices

Choice types (general discriminated unions) for .NET Standard 1.0+
C#
1
star
63

JmesPath

1
star
64

xls2csv

Utility to format an Excel (BIFF5/BIFF8) worksheet as CSV
JavaScript
1
star
65

Rdatasets.cs

Collection of over a thousand R datasets packaged as a .NET Standard library
C#
1
star