简体   繁体   中英

How to map a wrapped value in fp-ts?

I have this code and I was wondering if I can transform the below pipe s into just one pipe ?

const result: TE.TaskEither<DataTransferError, readonly CoinMetadataDto[]> = pipe(
  this.ensureFundsExist(),
  TE.chain((funds) => {
    return pipe(
      funds.map((fund) => {
        return this.coinGeckoAdapter.getCoinMetadata(fund.coinGeckoId);
      }),
      TE.sequenceArray,
    );
  }),
);

In other words can I map a TaskEither<E, Data[]> into a TaskEither<E, OtherData[]> in one go?

Instead of using Array.prototype.map ( funds.map ), you can use the curried map from the ReadonlyArray fp-ts module. Combine this with flow (left-to-right function composition) and you can get rid of the nested pipe :

import * as RA from 'fp-ts/ReadonlyArray'

const result: TE.TaskEither<DataTransferError, readonly CoinMetadataDto[]> = pipe(
  this.ensureFundsExist(),
  TE.chain(
    flow(
      RA.map(fund => this.coinGeckoAdapter.getCoinMetadata(fund.coinGeckoId)),
      TE.sequenceArray
    )
  )
);

However, there's an even better way of doing this using traverseArray :

export declare const traverseArray: <A, B, E>(
  f: (a: A) => TaskEither<E, B>
) => (as: readonly A[]) => TaskEither<E, readonly B[]>

TE.traverseArray(f) is equivalent to flow(RA.map(f), TE.sequenceArray) .

const result: TE.TaskEither<DataTransferError, readonly CoinMetadataDto[]> = pipe(
  this.ensureFundsExist(),
  TE.chain(
    TE.traverseArray(fund =>
      this.coinGeckoAdapter.getCoinMetadata(fund.coinGeckoId)
    )
  )
);

For more information, have a look at the Traversable type class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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