RSCG – Funcky.DiscriminatedUnion
| name | Funcky.DiscriminatedUnion |
| nuget | https://www.nuget.org/packages/Funcky.DiscriminatedUnion/ |
| link | https://github.com/polyadic/funcky-discriminated-union |
| author | Polyadic |
Generating discriminated unions for C# 9.0 and above.
This is how you can use Funcky.DiscriminatedUnion .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Funcky.DiscriminatedUnion" Version="1.1.0" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
The code that you will use is
using Union; Console.WriteLine("Save or not"); var data = SaveToDatabase.Save(0); Console.WriteLine(data.Match(ok => true,error => false)); data = SaveToDatabase.Save(1); Console.WriteLine(data.Match(ok => true,error => false));
namespace Union;
[Funcky.DiscriminatedUnion]
public abstract partial record ResultSave
{
public partial record Success(int Value): ResultSave;
public partial record ValidationError(string Message):ResultSave;
//public sealed partial record Ok(T Value) : ResultSave<T>;
//public sealed partial record Error(Exception Exception) : ResultSave<T>;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Union;
internal class SaveToDatabase
{
public static ResultSave Save(int i)
{
if (i == 0)
{
return new ResultSave.ValidationError(" cannot save 0");
}
return new ResultSave.Success(i);
}
}
The code that is generated is
// <auto-generated/>
#nullable enable
namespace Funcky
{
[global::System.Diagnostics.Conditional("Funcky_DiscriminatedUnion")]
[global::System.AttributeUsage(global::System.AttributeTargets.Class)]
internal sealed class DiscriminatedUnionAttribute : global::System.Attribute
{
/// <summary>Allow only consumers in the same assembly to use the exhaustive <c>Match</c> and <c>Switch</c> methods.</summary>
public bool NonExhaustive { get; set; }
/// <summary>Generates exhaustive <c>Match</c> and <c>Switch</c> methods for the entire type hierarchy.</summary>
public bool Flatten { get; set; }
/// <summary>Customized the generic type name used for the result in the generated <c>Match</c> methods. Defaults to <c>TResult</c>.</summary>
public string? MatchResultTypeName { get; set; }
}
}
// <auto-generated/>
#nullable enable
namespace Union
{
partial record ResultSave
{
[global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration","1.1.0.0")]
public abstract TResult Match<TResult>(global::System.Func<Success,TResult> success,global::System.Func<ValidationError,TResult> validationError);
[global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration","1.1.0.0")]
public abstract void Switch(global::System.Action<Success> success,global::System.Action<ValidationError> validationError);
partial record Success
{
[global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration","1.1.0.0")]
public override TResult Match<TResult>(global::System.Func<Success,TResult> success,global::System.Func<ValidationError,TResult> validationError) => success(this);
[global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration","1.1.0.0")]
public override void Switch(global::System.Action<Success> success,global::System.Action<ValidationError> validationError) => success(this);
}
partial record ValidationError
{
[global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration","1.1.0.0")]
public override TResult Match<TResult>(global::System.Func<Success,TResult> success,global::System.Func<ValidationError,TResult> validationError) => validationError(this);
[global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration","1.1.0.0")]
public override void Switch(global::System.Action<Success> success,global::System.Action<ValidationError> validationError) => validationError(this);
}
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Funcky.DiscriminatedUnion
Leave a Reply