Code Monkey home page Code Monkey logo

Comments (6)

rrousselGit avatar rrousselGit commented on July 23, 2024 1

Closing in favor of #907, which enables more advanced class hierarchies.

Alternatively, you can use @Implements/@With to do things by hand.

from freezed.

rrousselGit avatar rrousselGit commented on July 23, 2024

That is currently not supported.
But, it is not impossible to support it.

A more complex case I would like to fully support is:

abstract class Complex with _$Complex {
  const factory Complex.a(int value) = ComplexA;
  const factory Complex.b(double value) = ComplexB;
}

I'm thinking of a few things for these cases:

Complex example = Complex.a(42);

num value = example.value; // fine
double value = example.value // implicit-cast error, value is a num not a double

example.value would be num because that is the nearest common type between double and int

Then one more difficult scenario would be:

abstract class ReallyComplex with _$ReallyComplex {
  const factory ReallyComplex.a(int variable) = ReallyComplexA;
  const factory ReallyComplex.b(double variable) = ReallyComplexB;
  const factory ReallyComplex.c() = ReallyComplexC;
}

In which case I think I'd go with:

ReallyComplex example;

example.$variable(
  (num variable) => print(variable),
  orElse: () => print('nothing'),
);

The $ being necessary so that we can still do:

ReallyComplex example;
if (example is ReallyComplexA) {
  print(example.value);
} 

from freezed.

atreeon avatar atreeon commented on July 23, 2024

what would that look like for my example?

abstract class Result with _$Result {
  const factory Result.Continue(Action action) = Result_Continue;
  const factory Result.Retry(Action action) = Result_Retry;
  const factory Result.Complete() = Result_Complete;
}

result.$variable(
  (Action action) => process(action),
  orElse: () => print('nothing'),
);

and if I wanted to differentiate between continue and retry I would have to vary my type (ActionContinue or ActionRetry or something like that)

abstract class Result with _$Result {
  const factory Result.Continue(ActionContinue action) = Result_Continue;
  const factory Result.Retry(ActionRetry action) = Result_Retry;
  const factory Result.Complete() = Result_Complete;
}

result.$variable(
  (ActionContinue action) => process(action),
  (ActionRetry action) => wait 5.then(process(action)),
  orElse: () => print('nothing'),
);

...if I have that right then I think that would work well. It would be nice to vary by the continue and Retry types though and not by the parameters. In my example an Action is always an Action but the Result is the type that determines whether an action should Continue or Retry), maybe that is impossible as everything works around the parameters and not the types? but, if the syntax is possible, maybe an as keyword could work?

abstract class Result with _$Result {
  const factory Result.Continue(Action action) = Result_Continue as ResultAction;
  const factory Result.Retry(Action action) = Result_Retry as ResultAction;
  const factory Result.Complete() = Result_Complete;
}

result.maybeWhen(
  ResultAction: (action) => process(action,
  orElse: () => 'fallback',

or

result.maybeWhen(
  Result_Continue: (action) => process(action),
  Result_Retry: (action) => retry(action),
  orElse: () => 'fallback',

from freezed.

rrousselGit avatar rrousselGit commented on July 23, 2024

An alternative is to make the properties that are not shared between all constructors nullable.

Since Dart will "soon" have non-nullable types, it should be compile safe.

Freezed could still generate that$my_property variant for more complex cases.

from freezed.

atreeon avatar atreeon commented on July 23, 2024

I haven't thought this through that much (!) but could you go for a ducktyping approach? In my example above all I really want to do is run code wherever I have a property called action of type Action.

abstract class Result with _$Result {
  const factory Result.Continue(Action action) = Result_Continue;
  const factory Result.Retry(Action action, int retryTime) = Result_Retry;
  const factory Result.Complete() = Result_Complete;
}

main() {
  var result = Result_Continue(Action());

  result.maybeWhen(
    action: () => print("action"),
    action_retryTime: () => print("action in retrytime"),
    retryTime: () => print("retry time")
    _void: () => print("everything "),
  );
}

vary by the property names rather than the types because an int may not be descriptive enough - age & height for example could be two different parameters

from freezed.

CodingSoot avatar CodingSoot commented on July 23, 2024

A more complex case I would like to fully support is:

abstract class Complex with _$Complex {
  const factory Complex.a(int value) = ComplexA;
  const factory Complex.b(double value) = ComplexB;
}

For this specific case, we just have to add an abstract getter with the nearest common type :

abstract class Complex with _$Complex {
  const factory Complex.a(int value) = ComplexA;
  const factory Complex.b(double value) = ComplexB;

  num get value;
}

from freezed.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.