如何实现Arrow-KT Either组合为UserData类型的ApiResult?
合并多个Arrow-KT Either实现collectSomeHow函数
在Arrow-KT中,要合并多个Either(即ApiResult别名)并组合成目标类型,有两种常用实现方式:
方式一:使用zip操作符(推荐,简洁直观)
Arrow-KT的Either内置了zip操作符,可链式合并多个实例。当所有Either均为Right时,会将对应值传入转换函数生成新的Right;若任意一个为Left,则直接返回第一个出现的Left异常。
fun collectSomeHow( name: ApiResult<String>, age: ApiResult<Int>, email: ApiResult<String> ): ApiResult<UserData> = name.zip(age) { userName, userAge -> Pair(userName, userAge) } .zip(email) { (userName, userAge), userEmail -> UserData(userName, userAge, userEmail) }
方式二:手动嵌套fold处理
如果需要更细粒度的控制(比如自定义异常处理逻辑),可以通过嵌套fold方法逐一处理每个Either的Left和Right分支:
fun collectSomeHow( name: ApiResult<String>, age: ApiResult<Int>, email: ApiResult<String> ): ApiResult<UserData> = name.fold( onLeft = { Either.Left(it) }, onRight = { userName -> age.fold( onLeft = { Either.Left(it) }, onRight = { userAge -> email.fold( onLeft = { Either.Left(it) }, onRight = { userEmail -> Either.Right(UserData(userName, userAge, userEmail)) } ) } ) } )
额外说明
- 上述两种实现均遵循Arrow-KT的
Either语义:只要有一个请求返回Left(异常),最终结果就为该异常;只有所有请求都返回Right,才会组合成UserData并返回Right。 - 如果需要收集所有异常而非仅返回第一个,可自定义一个异常容器(比如
List<Exception>),在fold过程中累加异常,最后判断是否有异常并返回对应结果。
内容的提问来源于stack exchange,提问作者Erez Ben Harush
相关产品推荐
相关产品推荐

