Vavr中Either flatMap类型混淆编译错误排查求助
问题:Vavr Either.flatMap 类型推断失败导致编译错误
使用Vavr的Either进行链式操作时,调用flatMap方法出现编译错误,提示无法推断类型变量U。手动编写业务代码和IntelliJ自动生成的Function均无法编译,明明U应为Department类型却报错,需排查原因及解决方法。
原业务代码
@Override public Either<? extends ApplicationError, Department> createDepartment(CreateDepartmentCommand command) { Either<? extends ApplicationError, Department> department = Department.create(command.id(), command.name()); Either<? extends ApplicationError, Department> createdDepartment = department.flatMap((Department dep) -> { Optional<Department> existingDepartment = getDepartmentDrivenPort.getByName(command.name()); if (existingDepartment.isPresent()) { Either<? extends ApplicationError, Department> left = Either.left(new DepartmentExistsError()); return left; } else { Either<? extends ApplicationError, Department> right = createDepartmentDrivenPort.create(dep); return right; } }); return createdDepartment; }
编译错误信息
java: method flatMap in interface io.vavr.control.Either<L,R> cannot be applied to given types; required: java.util.function.Function<? super com.codependent.hexapp.application.domain.Department,? extends io.vavr.control.Either<capture#1 of ? extends com.codependent.hexapp.application.domain.error.ApplicationError,? extends U>> found: (Departmen[...]; } } reason: cannot infer type-variable(s) U (argument mismatch; bad return type in lambda expression io.vavr.control.Either<capture#2 of ? extends com.codependent.hexapp.application.domain.error.ApplicationError,com.codependent.hexapp.application.domain.Department> cannot be converted to io.vavr.control.Either<capture#1 of ? extends com.codependent.hexapp.application.domain.error.ApplicationError,? extends U>)
IntelliJ自动生成的Function代码及错误
自动生成代码
department.flatMap(new Function<Department, Either<? extends ApplicationError, ?>>() { @Override public Either<? extends ApplicationError, ?> apply(Department department) { return null; } });
对应编译错误
java: method flatMap in interface io.vavr.control.Either<L,R> cannot be applied to given types; required: java.util.function.Function<? super com.codependent.hexapp.application.domain.Department,? extends io.vavr.control.Either<capture#1 of ? extends com.codependent.hexapp.application.domain.error.ApplicationError,? extends U>> found: <anonymous java.util.function.Function<com.codependent.hexapp.application.domain.Department,io.vavr.control.Either<? extends com.codependent.hexapp.application.domain.error.ApplicationError,?>>> reason: cannot infer type-variable(s) U (argument mis
原因分析
核心问题是使用了通配符? extends ApplicationError作为Either的左类型,导致Java编译器无法确定具体的类型边界。Vavr的flatMap要求返回的Either左类型必须与原Either的左类型兼容,而通配符带来的类型不确定性让编译器无法推断出U的具体类型。
解决方法
方法1:替换通配符为具体错误类型
将Either的左类型从? extends ApplicationError改为ApplicationError(所有错误子类都可向上转型为该类型),让编译器明确类型边界:
@Override public Either<ApplicationError, Department> createDepartment(CreateDepartmentCommand command) { Either<ApplicationError, Department> department = Department.create(command.id(), command.name()); Either<ApplicationError, Department> createdDepartment = department.flatMap(dep -> { Optional<Department> existingDepartment = getDepartmentDrivenPort.getByName(command.name()); if (existingDepartment.isPresent()) { return Either.left(new DepartmentExistsError()); } else { return createDepartmentDrivenPort.create(dep); } }); return createdDepartment; }
方法2:显式指定flatMap的类型参数
如果必须保留通配符,可以显式指定flatMap的泛型参数,帮助编译器推断:
Either<? extends ApplicationError, Department> createdDepartment = department.<ApplicationError, Department>flatMap(dep -> { Optional<Department> existingDepartment = getDepartmentDrivenPort.getByName(command.name()); if (existingDepartment.isPresent()) { return Either.left(new DepartmentExistsError()); } else { return createDepartmentDrivenPort.create(dep); } });
推荐使用方法1,避免通配符带来的类型模糊问题,使代码更简洁易读。
内容的提问来源于stack exchange,提问作者codependent
相关产品推荐
相关产品推荐

