language-ext v3.3.30 Release Notes

Release Date: 2019-11-09 // over 4 years ago
  • 🚀 In this release the code-generation story has been extended to support sum-types (also known as 'discriminated unions', 'union types', or 'case types').

    Simply declare an interface with the attribute [Union] where all methods declared in the interface return the type of the interface, i.e.

     [Union] public interface Maybe\<A\> { Maybe\<A\> Just(A value); Maybe\<A\> Nothing(); }
    

    It has similar behaviour to this, in F#:

    type Maybe\<'a\> =| Just of 'a | Nothing
    

    In the above example, two case-types classes will be created Just<A> and Nothing<A> as well as static constructor class called Maybe:

    var maybe = Maybe.Just(123); var res = maybe switch { Just\<int\> just =\> just.Value, Nothing\<int\> \_ =\> 0 };
    

    This is the generated code:

    public partial class Just\<A\> : LanguageExt.Record\<Just\<A\>\>, Maybe\<A\> { public readonly A Value; Maybe\<A\> Maybe\<A\>.Just(A value) =\> throw new System.NotSupportedException(); Maybe\<A\> Maybe\<A\>.Nothing() =\> throw new System.NotSupportedException(); public Just(A value) { Value = value; } } public partial class Nothing\<A\> : LanguageExt.Record\<Nothing\<A\>\>, Maybe\<A\> { Maybe\<A\> Maybe\<A\>.Just(A value) =\> throw new System.NotSupportedException(); Maybe\<A\> Maybe\<A\>.Nothing() =\> throw new System.NotSupportedException(); public Nothing() { } } public static partial class Maybe { public static Maybe\<A\> Just\<A\>(A value) =\> new Just\<A\>(value); public static Maybe\<A\> Nothing\<A\>() =\> new Nothing\<A\>(); }
    

    👍 The generated code is relatively basic at the moment. It will be extended to support abstract class types and will auto-generate structural equality behaviour as well as other useful behaviours. But for now this is a super-quick way to generate the cases for a union-type and have a simple way of constructing them.

    The generated types are all partial and can therefore be extended trivially.

    Here's another simple example:

     [Union] public interface Shape { Shape Rectangle(float width, float length); Shape Circle(float radius); Shape Prism(float width, float height); }
    

    And the generated code:

    public partial class Rectangle : LanguageExt.Record\<Rectangle\>, Shape { public readonly float Width; public readonly float Length; Shape Shape.Rectangle(float width, float length) =\> throw new System.NotSupportedException(); Shape Shape.Circle(float radius) =\> throw new System.NotSupportedException(); Shape Shape.Prism(float width, float height) =\> throw new System.NotSupportedException(); public Rectangle(float width, float length) { Width = width; Length = length; } } public partial class Circle : LanguageExt.Record\<Circle\>, Shape { public readonly float Radius; Shape Shape.Rectangle(float width, float length) =\> throw new System.NotSupportedException(); Shape Shape.Circle(float radius) =\> throw new System.NotSupportedException(); Shape Shape.Prism(float width, float height) =\> throw new System.NotSupportedException(); public Circle(float radius) { Radius = radius; } } public partial class Prism : LanguageExt.Record\<Prism\>, Shape { public readonly float Width; public readonly float Height; Shape Shape.Rectangle(float width, float length) =\> throw new System.NotSupportedException(); Shape Shape.Circle(float radius) =\> throw new System.NotSupportedException(); Shape Shape.Prism(float width, float height) =\> throw new System.NotSupportedException(); public Prism(float width, float height) { Width = width; Height = height; } } public static partial class ShapeCon { public static Shape Rectangle(float width, float length) =\> new Rectangle(width, length); public static Shape Circle(float radius) =\> new Circle(radius); public static Shape Prism(float width, float height) =\> new Prism(width, height); }
    

    ⚡️ > NOTE: The code-gen doesn't yet support .NET Core 3.0 - I'm still waiting for the Roslyn code-gen project to be updated. If it isn't forthcoming soon, I'll look for other options.