Scifa.UnionTypes 0.0.24

dotnet add package Scifa.UnionTypes --version 0.0.24                
NuGet\Install-Package Scifa.UnionTypes -Version 0.0.24                
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="Scifa.UnionTypes" Version="0.0.24" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Scifa.UnionTypes --version 0.0.24                
#r "nuget: Scifa.UnionTypes, 0.0.24"                
#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 Scifa.UnionTypes as a Cake Addin
#addin nuget:?package=Scifa.UnionTypes&version=0.0.24

// Install Scifa.UnionTypes as a Cake Tool
#tool nuget:?package=Scifa.UnionTypes&version=0.0.24                

Union Types

Allowing C# to represent unions. Also known as "sum types" or "intersection types", union types allow modelling the concept of a thing being either A OR B.

Examples:

  • Modelling PATCH operations: a value could either be set or not set (Option/Maybe type)
  • A call to a database will result in either a dataset or an error (Result type)
  • Money coming into your bank account could be income or a refund from a shop or someone paying you back for something

How to use

  1. Install the package
  2. create a partial type and annotate with [UnionType]
  3. Add static partial methods returning the containing type - these methods can be named anythign you like and can take any arguments you like (but no ref/in/out params!)
  4. Scifa.UnionTypes generates constructors, fields, Match and Do methods for you.

Examples

Option<T> = None | Some(T)

using UnionTypes; // 1. Install the package

[UnionType] // 2. create a type and annotate with `[UnionType]`
public readonly partial record struct Option<T>
{
    // 3. Add static methods returning the containing type
    public static partial Option<T> None();
    public static partial Option<T> Some(T value);


    // Map and Bind are common methods on option types
    public Option<TOut> Map<TOut>(Func<T, TOut> mapper)
        => Match(
            none: () => Option<TOut>.None(),
            some: x => Option<TOut>.Some(mapper(x))
        );
    public Option<TOut> Bind<TOut>(Func<T, Option<TOut>> mapper)
        => Match(
            none: () => Option<TOut>.None(),
            some: x => mapper(x)
        );
}

Singly-linked list LList<T> = Empty | Node<T>

using Scifa.UnionTypes;

[UnionType]
public readonly partial record struct LList<T>
{
    public static partial LList<T> Empty();
    public static partial LList<T> Node(T value, LList<T> next);
}
var list = LList.Node(1, LList.Node(2, LList.Node(3, LList.Empty())));

Isn't this the same thing as OneOf?

Yeah, pretty much. I wrote this becuase I prefer the specific types than generic catch-all types and I wanted something which would work nicely with structs too. As a bonus, it appears to be a little bit faster (though with slightly larger code size) but that wasn't the primary goal.

// * Summary *

BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22000.1574/21H2/SunValley)
Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=7.0.100
  [Host]     : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
  DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2


|                                Method |      Mean |     Error |    StdDev | Ratio | Code Size | Allocated | Alloc Ratio |
|-------------------------------------- |----------:|----------:|----------:|------:|----------:|----------:|------------:|
|             CreateAndMatch_None_OneOf | 10.546 ns | 0.0729 ns | 0.0646 ns |  1.00 |     333 B |         - |          NA |
|        CreateAndMatch_None_UnionTypes |  6.391 ns | 0.0770 ns | 0.0643 ns |  0.61 |     389 B |         - |          NA |
| CreateAndMatch_None_UnionTypes_static |  6.289 ns | 0.0464 ns | 0.0411 ns |  0.60 |     389 B |         - |          NA |
|                                       |           |           |           |       |           |           |             |
|             CreateAndMatch_Some_OneOf | 10.868 ns | 0.0976 ns | 0.0815 ns |  1.00 |     336 B |         - |          NA |
|        CreateAndMatch_Some_UnionTypes |  6.496 ns | 0.0319 ns | 0.0298 ns |  0.60 |     404 B |         - |          NA |
| CreateAndMatch_Some_UnionTypes_static |  6.493 ns | 0.0506 ns | 0.0449 ns |  0.60 |     404 B |         - |          NA |
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

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
0.0.24 140 8/20/2024
0.0.23 114 8/20/2024
0.0.22 109 8/20/2024
0.0.21 114 8/20/2024
0.0.20 112 6/20/2024
0.0.19 114 6/13/2024
0.0.17 115 6/13/2024
0.0.16 81 5/31/2024
0.0.15 68 5/31/2024
0.0.14 68 5/31/2024
0.0.13 94 5/31/2024
0.0.12 91 5/31/2024
0.0.11 118 4/29/2024
0.0.10 121 4/24/2024
0.0.9 111 4/23/2024
0.0.8 790 8/9/2023
0.0.7 279 8/9/2023
0.0.6 260 8/9/2023
0.0.5 239 8/7/2023
0.0.4 234 8/7/2023
0.0.3 156 8/7/2023
0.0.2.1 211 3/18/2023
0.0.2 304 2/2/2023
0.0.1 326 1/25/2023