-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion: Unions/closed hierarchies/ADTs, which one does C# 7.1+ need & what would the spec look like? #75
Comments
Does your approach allow nested records? Let's say I want to express something like this in C#: type Expr =
| Const of int
| Bin of Op * Expr * Expr except |
public struct Color(int R, int G, int B);
public enum CommonColors : Color
{
Blue = new Color(0, 0, 255),
Green = new Color(0, 255, 0),
Red = new Color(255, 0, 0)
} Or using tuples- public enum CommonColors : (int Red, int Green, int Blue)
{
Blue = (0, 0, 255),
Green = (0, 255, 0),
Red = (255, 0, 0)
}
class Person(string first, string last); // a record type
enum interface IntOrBool
{
class I: int;
class B: bool;
}
enum interface MixedType
{
class T: (int, int);
class P: Person;
class L: IList<int>;
class U: IntOrBool;
} I would really like to use a new keyword enum type MixedType
{
class T(int first, int second);
class Person(string first, string last);
class L: IList<int>;
class U: enum type IntOrBool
{
class I: int;
class B: bool;
};
} The enum type Option<T>
{
class None;
class Some: T;
} Similarly the enum type Result<T>
{
class Success: T;
class Failure: Exception;
} |
@orthoxerox This F# DU- type Expr =
| Const of int
| Bin of Op * Expr * Expr will become this in C# according to my proposal- enum type Expr
{
class Const: int;
class Bin: (Op, Expr, Expr);
} |
/cc @agocke |
IMO, anonymous types and named types might have to be compatible, or at least should be consistent.
This might apply to Unions too. So isn't it necessary to discuss also about anonymous unions? function padLeft(value: string, padding: string | number) {
// ...
} I want both named and anonymous Unions in C# and their syntax are consistent. e.g.
|
I don't believe that DU's should be limited to a set of types with a common base type. It probably makes sense to maintain as much compatibility with F# DU's as feasible, as that could even then allow them to be used interchangeably. However, looking at your examples, I may simply be misunderstanding what you mean as you then show union types with no common base type. |
In my proposal, I am using a special sealed, internally-auto-implemented kind of interface as a base type, instead of an abstract class. Because class as a base type will require multiple inheritance of some sort. So, in this example (using enum interface Result<T>
{
class Success: T {}
class Failure: Exception {}
}
|
@DavidArno I do not expect to spend much time on DUs until the work on records settles down. I leave it to you to decide where best to continue conversations about approaches to DUs. |
[Please note, I'd like to use this thread to build a proper proposal for union types in C#, so this will be edited over time to take into account feedback to build it into a proposal]
A group of related features requested many times in the Roslyn repo is for something similar to F#'s discriminated unions. The proposals use various names for these type collections: unions, ADTs (arithmetic data types), closed hierarchies, hierarchy data types etc.
In addition, numerous different syntaxes have been proposed, re-using
enum
.abstract
andsealed
to denote it's a union as well as varying greatly in the syntax within the type.Lastly, just to add to the confusion, separate proposals for enum types similar to that supported by Java have also come and gone. These threads then often morph into discussions around unions too.
Rather than list all the existing proposals, the following two seem a useful starting point as they then link to many of the other proposals:
[C# Feature Request] Hierarchy Data Type
Proposal: Add Discriminated Unions using a new Type
Please note, this proposal doesn't cover closed sets of values, as discussed in Proposal: Record Enum Types as they potentially infringe on a Java "patent" (see that thread for details). It is only concerned with closed sets of types.
Declaring a union
An example of a union from F# for fun and profit is:
Using C# records, this could potentially be expressed in C#, using a form of union definition syntax, as:
Constructing a union instance
As the underlying type of the above union is
MixedType
, it might be necessary to use the following syntax to construct them:It would be desirable to be able to express it as following though, but this could lead to name resolution issues(?):
i,e, the
MixedType
part has been dropped and the "subtype" names are used directly.Pattern matching
Using the "subtype" names directly and the upcoming
match
expression, a pattern match of a union might look like:Generics
The exemplar union type of
Option<T.
(chosen overMaybe<T>
as the former is used by F#) could be declared as:Obvious questions
var x = default(MixedType)
handled, to ensure it results in a meaningful value?The text was updated successfully, but these errors were encountered: