简体   繁体   English

fp-ts,如何获取TaskEithers数组,在每个项目中运行一个function,然后将选项分成两个arrays?

[英]fp-ts, how to take an array of TaskEithers, run a function in each item then split the options into two arrays?

I am trying to write the following code with fp-ts.我正在尝试使用 fp-ts 编写以下代码。

imperative:至关重要的:

export async function runTest(globString) {
  let passed = 0;
  let failed = 0;
  const files = glob.sync(globString);
  for (let i = 0; i < files.length; i++) {
    // eslint-disable-next-line no-await-in-loop
    const module = await import(`./${path.relative(__dirname, files[i])}`);
    for (let z = 0; z < Object.keys(module).length; z++) {
      const testFn = Object.keys(module)[z];
      // eslint-disable-next-line no-await-in-loop
      const result = await module[testFn]()
      // eslint-disable-next-line no-plusplus
      if (result) { passed++ } else { failed++ };
      console.log(`${result ? `✅` : `❌`} ${module[testFn].description || testFn}`)
    }
  }
  console.log(`✅ ${passed} tests passed`);
  console.log(`❌ ${failed} tests failed`);
}

the functions applied can be divided into two:应用的功能可以分为两种:

the one that imports the file from the glob.从全局导入文件的那个。 the second that runs the function.第二个运行 function。

We can even omit the console logs, I am stuck where I should read the right values but I am not what should to that the data out of this Right, and also eventually have the Left in a separated array.我们甚至可以省略控制台日志,我被困在应该读取正确值的位置,但我不应该从这个 Right 中读取数据,并且最终将 Left 放在一个单独的数组中。 Any ideas?有任何想法吗?

const importModule = (string) => import(`./${path.relative(__dirname, string)}`)
export const runTest = (globString) => pipe(
  glob.sync(globString),
  AR.map(TE.tryCatchK(importModule, id)),
  AR.map(TE.bimap(id, Object.values)),
  AR.map(TE.bimap(id, AR.map(fn => [fn(), fn.name]))),
  async a => console.log(await a[0]()) //{_tag: 'Right', right: Array(15)}
)
//number of items is correct but I am stuck here.

EDIT:编辑:

got the code improved now it works by capturing the errors into the Eithers and I do have an array of Eithers.现在改进了代码,它通过将错误捕获到 Eithers 中来工作,而且我确实有一个 Eithers 数组。

export const runTest = (globString) => pipe(
  glob.sync(globString),
  x => [...x, 'tras'], //last item will throw an error it is on purpose
  AR.map(TE.tryCatchK(async str => Object.values((await importModule(str))), id)),
  AR.sequence(T.ApplicativePar),
  async a => (await a()).map(console.log)
)

Now the rights in the Array are arrays as well, so I have Task<Array<Either<E,Array>>> and I need Task<Array<Either<E,Function>, problem now is that if I try to sequence I lose the rights现在数组中的权限也是 arrays,所以我有 Task<Array<Either<E,Array>>> 并且我需要 Task<Array<Either<E,Function>,现在的问题是如果我尝试对我进行排序失去权利

For anyone wondering I ended up with the following.对于任何想知道我最终得到以下结果的人。

const safeRunFn = f => TE.tryCatchK(
  async (s) => await f() && `✅ ${f.description || f.name} - passed`,
  (e) => `❌ ${f.description || f.name} - failed \n${e}`
)(f);

const safeImport = z => TE.tryCatchK(
  (s) => import(`./${path.relative(__dirname, s)}`),
  (e) => `❌ ${z} - failed \n${e}`
)(z);

export const runTest = (globString) => pipe(
  glob.sync(globString),
  x => [...x, 'tras'],
  A.map(safeImport),
  A.map(TE.map(Object.values)),
  A.map(TE.chain(TE.traverseArray(safeRunFn))),
  A.map(TE.match(id, id)),
  T.sequenceArray,
  T.map(x => x.flat())
  //A.flatten throws the error below, not sure why.
  //Uncaught TypeError TypeError: CreateListFromArrayLike called on non-object
)

Any ideas how this can be improved are welcome.欢迎任何想法如何改进。

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

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