The JohnAz.CSharp.UnionTypes library can be installed from NuGet.
PM> NuGet\Install-Package JohnAz.CSharp.UnionTypes
.csunion
file. We have a special DSL for this with a syntax that should be familiar to C# users: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.
.csunion
file is processed by a Source Generator, which then generates the appropriate objects to implement the discriminated union in C#.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>;
}
}
Maybe<T>
type in our code with of switch expressions to properly handle the various cases.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
.csunion
in your project and set its type to Analyser Additional File
..csunion
file above.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.