简体   繁体   English

fp-ts 如何处理不同权限类型的多个 Either

[英]fp-ts How to Handle Multiple Eithers with Different Right Types

What is the best way to handle Promise s of Either s when the Right side of the Either s do not align nicely?Either的右侧没有很好地对齐时,处理EitherPromise s 的最佳方法是什么? In this scenario, I have three non-dependent, "prerequisite" operations represented as Either s (with different right hand types).在这种情况下,我有三个非依赖的“先决条件”操作,表示为Either s(具有不同的右手类型)。 If they all succeed, I wan't to proceed with the fourth operation.如果他们都成功了,我不想进行第四次手术。 If any of the three fails, I do not wan't to proceed with the fourth operation.如果三者中任何一个失败,我都不想进行第四次手术。

At this point, I have a solution compiling, but am not happy with readability.此时,我有一个正在编译的解决方案,但对可读性不满意。 Surely there is a more elegant way to handle the multiple Either s in this type of scenario?在这种情况下,肯定有更优雅的方法来处理多个Either吗?

    //promise of Either<ApiError, CustomerDTO>
    const customer = this.customerService.createCustomer(siteOrigin, createCustReq);

    //promise of Either<ApiError, LocationDTO>
    const location = this.locationService.getRetailOnlineLocation(siteOrigin);

    //promise of Either<ApiError, StationDTO>
    const station = this.stationService.getRetailOnlineStation(siteOrigin);
    
    //execute previous concurrently
    const locationAndStationAndCustomer = await Promise.all([location, station, customer]);

    const locationE = locationAndStationAndCustomer[0];
    const stationE = locationAndStationAndCustomer[1];
    const customerE = locationAndStationAndCustomer[2];


    //How to make this better?
    const stationAndLocationAndCustomer = E.fold(
      (apiErr: ApiError) => E.left(apiErr),
      (location: LocationDTO) => {
        return E.fold(
          (apiErr: ApiError) => E.left(apiErr),
          (station: StationDTO) =>
            E.right(
              E.fold(
                (err: ApiError) => E.left(err),
                (customer: CustomerDTO) =>
                  E.right({ location, station, customer })
              )(customerE)
            )
        )(stationE);
      }
    )(locationE);

I think the comments were getting close to the right answer.我认为评论已经接近正确答案了。 sequenceT is a correct approach to this type of problem. sequenceT是解决此类问题的正确方法。

import { sequenceT } from 'fp-ts/Apply'
import * as E from 'fp-ts/Either';

const seq = sequenceT(E.Apply);

return pipe(
  await Promise.all([location, station, customer]),
  seq, // [Either<...>, Either<...>, Either<...>] => Either<ApiError, [...]>
  // map is a bit less cumbersome. If the value was Left it returns Left
  // otherwise it calls the function which returns a new Right value from
  // what the function returns
  E.map(([loc, sta, cust]) => ({
    location: loc,
    station: sta,
    customer: cust,
  })), 
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM