Skip to content

Instantly share code, notes, and snippets.

@pblasucci
Last active April 23, 2021 11:44
Show Gist options
  • Save pblasucci/34f675e3b803b3c3cf9f26f423b48b50 to your computer and use it in GitHub Desktop.
Save pblasucci/34f675e3b803b3c3cf9f26f423b48b50 to your computer and use it in GitHub Desktop.
Exposing Discriminaed Unions from F# to C#
using System;
using FsLibrary;
namespace CsConsumer
{
public static class Program
{
public static void Main(string[] _)
{
var msg = Vsn.DefaultScheme.Either(
unknown: () => "Unknown",
serial: rev => $"r{rev}",
semantic: (m, n, p) => $"v{m}.{n}.{p}"
)
Console.WriteLine(msg);
}
}
}
namespace FsLibrary
type Vsn = {
Scheme : VsnScheme
Suffix : string option
} with
static member DefaultSchema = VsnScheme.Unknown
and VsnScheme =
| Unknown
| Serial of revision : uint64
| Semantic of major : byte * minor : byte * patch : byte
// it's often useful to group the "C#-facing" API into separate components
[<Extension>]
type VsnExtensions =
[<Extension>]
static member Either
(
scheme : VsnScheme,
unknown : Func<'T>,
serial : Func<uint64, 'T>,
semantic : FromSemanticVsn<'T> // in addition to common delegates, using named delegates is also an option
) =
// null checks elided for clarity
match me with
| Unknown -> unknown.Invoke()
| Serial revision -> serial.Invoke(revision)
| Semantic (m, n, p) -> semantic.Invoke(m, n, p)
and FromSemanicVsn<'T> = delegate of (byte * byte * byte) -> 'T
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment