Skip to content

Proposal: Record Enum Types #6739

@alrz

Description

@alrz

Record Enum Types

Currently, enum types wouldn't be considered as complete patterns and they don't have any "record" syntax to be used in pattern matching. This proposal tries to fill this gap.

This proposal won't affect regular enum types like #3704, rather, it suggests an enum-like syntax for declaring flat hierarchies of ADTs (with both value and reference types).

Enum structs

Enum structs would be more like Java enum types, for example

public enum struct Color(int R, int G, int B) {
    Blue(0,0,255),
    Green(0,255,0),
    Red(255,0,0)
}

would translate to

public struct Color {
    public readonly static Color Blue = new Color(0, 0, 255);
    public readonly static Color Green = new Color(0, 255, 0);
    public readonly static Color Red = new Color(255, 0, 0);

    private Color(int R, int G, int B) {
        this.R = R;
        this.G = G;
        this.B = B;
    }

    public int R { get; }
    public int G { get; }
    public int B { get; }
}

Another example from Java docs:

public enum struct Planet(double Mass, double Radius) {
    Mercury (3.303e+23, 2.4397e6),
    Venus   (4.869e+24, 6.0518e6),
    Earth   (5.976e+24, 6.37814e6),
    Mars    (6.421e+23, 3.3972e6),
    Jupiter (1.9e+27,   7.1492e7),
    Saturn  (5.688e+26, 6.0268e7),
    Uranus  (8.686e+25, 2.5559e7),
    Neptune (1.024e+26, 2.4746e7),
    Pluto   (1.27e+22,  1.137e6);

    public const double G = 6.67300E-11;

    public double SurfaceGravity =>
        G * Mass / (Radius * Radius);

    public double SurfaceWeight(double otherMass) =>
        otherMass * SurfaceGravity;
}

This struct must not be instantiable, because of the completeness of the pattern.

Enum classes

Enum classes are useful for declaring flat hierarchy of ADTs (similar to F# discriminated unions). For example. the following

public sealed abstract class Option<T> {
    public sealed class Some(T Value) : Option<T>;
    public sealed class None() : Option<T>;
}

could be written as

public enum class Option<T> {
    Some(T value : Value),
    None;
}

With enum classes, abstract sealed would be considered as an advanced feature where you can declare more complicated ADTs.

Remarks

  • Each member translates to a subclass of the Option<T> in this example.
  • Enum classes are implicitly abstract and cannot extend any other types.
  • Enum class members can have a body to potentially override methods on the base (like Java).
public enum class Expr {
  Const(double Value)        { public override string ToString() => Value.ToString(); },
  Mul(Expr Left, Expr Right) { public override string ToString() => $"({Left} * {Right})"; },
  Add(Expr Left, Expr Right) { public override string ToString() => $"({Left} + {Right})"; },
  Div(Expr Left, Expr Right) { public override string ToString() => $"({Left} / {Right})"; },
  Sub(Expr Left, Expr Right) { public override string ToString() => $"({Left} - {Right})"; },
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions