-
Notifications
You must be signed in to change notification settings - Fork 213
type parameter in operator overloading #1044
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
Comments
The biggest issue with generic operators is that you can't pass them explicitly. It would be like a generic function where you could only use the type argument that was inferred, with no way to override it. It's not completely untenable. It makes sense to use generics as a kind of existential type predicate. extension FutX<T> on Future<T> {
Future<R> operator>><R>(FutureOr<R> Function(T) handler) => this.then<R>(handler);
}
...
future >> ((x) => x + 1) // wohoo (Getters and setters are even harder, and less useful, to make generic that way because they only have one moving part that you can type). |
Well, it would be even nicer if there was no distinction between operators and functions, but I know there's no viability in Dart. |
The distinction is mainly syntactical. The method If we introduced a way to call operators directly, say The real question here is how much of this is actually useful and therefore worth the effort. Allowing optional parameters seems spurious, but generics and a way to do tear-off and explicit invocation could be useful. There are parsing issues. Since both |
I was thinking that extensions might let you accomplish this: class C {}
extension<T> on C {
T operator |(T value) {
print("pipe $T");
return value;
}
}
main() {
var c = C();
c | true;
c | 123;
} But this prints:
So I guess type inference on extensions doesn't to upwards inference based on the RHS of an operator? |
@munificent the type of the arguments are not taken into account when resolving the generic type parameters of the extension. This was a deliberate choice, based on design discussion at the time. I'm not sure if it works for this use case, but you can change your code to be |
I would like to resurrect this one. I am working on various Monads for Dart, and they are quite verbose without operator overloading. It would be nice to have both generic type arguments and the ability to override arbitrary symbols. One issue is that Dart gets too brackety when you call extensions inside extensions and so on. The main issue is with the equivalent of Haskell's Will provide examples soon. |
I just ran into this. I have two types, |
Indeed, that won't work. You could (maybe) get around it with a generic method like: abstract class Foo {
Foo add<T extends Foo>(T other);
}
abstract class Bar extends Foo {
T add<T extends Foo>(T other);
}
abstract class Baz extends Foo {
Baz add<T extends Foo>(T other);
} but without generic operators, you can't do that with |
For what it's worth, I found my way here due to having nearly the exact same use case as dgreensp. In my case, I have a class which is essentially number with some fields and methods tacked on, so I wanted to be able to treat it largely as a number in defining operators (which means abstract class Foo {
final String name;
final num value;
const Foo({required this.name, required this.value});
static T create<T extends Foo>(num value) => switch (T) {
Bar => Bar(value) as T,
Baz => Baz(value) as T,
_ => throw TypeError(),
};
// Works, but requires `bar1.add<Bar>(bar2)` or `bar = Bar(bar.value).add(bar2)`.
T add<T extends Foo>(T addend) => Foo.create<T>(value + addend.value);
// Doesn't work, but would have allowed for use of `bar1 +<Bar> bar2` or `bar +=<Bar> bar2` instead.
T operator +<T extends Foo>(T addend) => Foo.create<T>(value + addend.value);
}
class Bar extends Foo {
const Bar(num value) : super(name: 'Bar', value: value);
}
class Baz extends Foo {
const Baz(num value) : super(name: 'Baz', value: value);
} While I can get around this by overloading the Maybe there's a better way of accomplishing what I'm aiming at in general, and generics on operators wouldn't be necessary if I did use whatever that alternative might be, but this is ultimately the kind of structure which led me to want this feature to be available in Dart. |
Dart does not support adding types in operator overloading.
It would be great if it is supported for function currying, piping using extension and operator overloading.
The text was updated successfully, but these errors were encountered: