Closed narcodico closed 4 years ago
Hi, @RollyPeres .
Your problem seems to be related to type inferentece and, thus, not related to dartz itself. Please, refer to #33 and #38, they are similar issues.
The problem probably will be solved simply by typecasting in the right place.
As I don't have the time to test your specific code right now, I may be wrong, so please feel free to tell me if this is not the case.
Hi @mateusfccp , thanks for suggestions. It clearly has something to do with type inference but couldn't find a solution. Also attempt
is not generic as suggested in #33 ...I'm using dartz: ^0.9.0-dev.5
.
Can you provide a minimal reproducible example?
@mateusfccp There you go: https://gist.github.com/RollyPeres/72c3d80e39bf032209c5b2aaea7b42e7
Well, your case is a little more complex. It seems Dart can't handle the "complex" case of T extends Either<Object, U>
and can't infer U
.
Let me ask: why have T to extend Either,<Object, U>
? In the MRE you provided, you are not using any extension of Either
, but Either
itself.
I managed to run your example by replacing every occurrence of T
with it's meaning:
extension TaskEitherExtensions<U> on Task<Either<Object, U>> {
Task<Either<AppFailure, U>> mapLeftToFailure() {
return map<Either<AppFailure, U>>(
(Either<Object, U> either) => either.leftMap<AppFailure>((error) {
if (error is AppFailure) return error;
// simplified code for brevity...
return AppFailure();
}),
);
}
}
Of course, this will cause another problem. You are returning a Future<String>
on something
when doSomething
expects Either<AppFailure, Unit>
. Changing Unit
to String
will solve this:
Future<Either<AppFailure, String>> doSomething() {
return Task(something).attempt().mapLeftToFailure().run();
}
Is this the expected behavior or am I missing something?
That was the problem. I've experimented with a couple of approaches, so apparently I ended up not paying attention to basic stuff :)
My end goal was to have:
extension TaskExtensions<T> on Task<T> {
Future<Either<AppFailure, T>> execute() => attempt().mapLeftToFailure().run();
}
This will greatly simplify all the boiler plate. Thanks @mateusfccp for having a fresh look at this!
I've made a couple of extension methods trying to simplify the extremely verbose syntax when using
Task
. I'm left mapping in case of a failure to preserve unexpected errors.And I wanna call it like:
However, I get
type 'Future<Either<AppFailure, dynamic>>' is not a subtype of type 'Future<Either<AppFailure, Unit>>'
I might be missing something here but is there a way of preserving type safety with my approach?