csharp-uniontypes

CSharp.UnionTypes

Documentation

Install


The JohnAz.CSharp.UnionTypes library can be installed from NuGet.

PM> NuGet\Install-Package JohnAz.CSharp.UnionTypes

Use


namespace Monads
{
  union Maybe<T> { Some<T> | None };
}

This indicates that a Maybe<T> type is either a Some wrapping a value of type T, or a None “marker” value.

Using value semantics provided by records in C# 9.0 and above, we can then generate the following code which implements the discriminated union.

namespace Monads
{
    public abstract partial record Maybe<T>
    {
        private Maybe() { }
        public sealed partial record Some(T Value) : Maybe<T>;
        public sealed partial record None() : Maybe<T>;
    }
}
public static void Main (string[] args)
{
    Maybe<int> m23 = new Maybe<int>.Some(23);

    Console.WriteLine(m23 switch
    {
        Maybe<int>.Some { Value: var v } => $"Some {v}",
        Maybe<int>.None => "None",
        _ => throw new NotImplementedException()
    });
}

In the code above, we create a Maybe<int> value of type Maybe<int>.Some wrapping an int value of 23, and then use a switch expression to print out the value Some 23.

To summarize

  1. Install the Nuget Package
  2. Add a file of type .csunion in your project and set its type to Analyser Additional File.
  3. Write an expression to define a Union type in the .csunion file above.
  4. Use the type as if you had written it yourself in C#. The source generator will have generated it for you in the background.
  5. Enjoy!

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests. If you’re adding a new public API, please also consider adding samples that can be turned into a documentation, or consider improving the tutorial. You might also want to read the library design notes to understand how it works.

The library is available under Public Domain license, which allows modification and redistribution for both commercial and non-commercial purposes. For more information see the License file in the GitHub repository.