Skip to content

More concise syntax for defining sealed families #3021

Open
@mraleph

Description

@mraleph

With sealed class families and pattern matching developers are understandably excited to use them for data modelling in their programs. However the syntax is overly verbose for simple families, e.g. modelling success / failure in the API requires writing something like this:

sealed class Result<T> {
  const Result();
}

class Ok<T> extends Result<T> {
   final T value;
   const Ok<T>(this.value);
}

class Error extends Result<Never> {
  final String message;
  const Error(this.message);
} 

With primary constructors this is reduced to

sealed class Result<T> {
  const Result();
}

class Ok<T>(final T value) extends Result<T>;
class Error(final String message) extends Result<Never>;

Which is much better but still has some repeated boilerplate here: repeated extends Result<*>.

I suggest expanding upon primary constructors and introduce a special syntactic sugar for simple sealed families like this

sealed class Result<T> {
  case Ok<T>(final T value);
  case Error(final String message);
} 

Here case C<T1, ..., Tn>(v0, ..., vN) { m1 ... mN }? occurring inside sealed class B<U1, ..., Un> gives raise to

class C<T1, ..., Tn>(v0, ..., vN) extends B<Forward({Ti}, {Ui})> {
  // Optional methods
  m1
  // ...
  mN
}

Forward(...) is defined as forwarding type parameters based on their names (or maybe indices - I am not sure what is better). If Ui does not have a corresponding Ti then Never is passed instead.

/cc @munificent @lrhn

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureProposed language feature that solves one or more problems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions