TaskEithersequenceArray函数处理不同类型返回类型的问题

问题描述 投票:0回答:2

我正在使用

fp-ts
库进行函数式编程。 这是我的代码和我的问题:

import * as TE from 'fp-ts/TaskEither';
import { pipe } from 'fp-ts/lib/function';

function getName(): TE.TaskEither<Error, String> {
  return TE.right('John Doe');
}

function getAge(): TE.TaskEither<Error, number> {
  return TE.right(40);
}

export function seqArrayTest(): TE.TaskEither<Error, string> {
  return pipe(
    TE.sequenceArray([
         getName(), 
         getAge(),
       ]),
    TE.chain(([name, age]) => {
      return TE.right(`Name: ${name}, Age: ${age}`);
    }),
  );
}

这里:

  1. 我有两个函数:
    getName
    getAge
    返回具有不同值类型的
    TaskEither
  2. 我使用
    TE.sequenceArray
    称它们为并行。
  3. 计算完成后,我只是链接响应并返回另一个
    TaskEither

在编译过程中,在

TE.sequenceArray([getName(), getAge()])
上,它显示以下
getAge()
错误:

类型“TaskEither”不可分配给类型“TaskEither”。 类型“number”不可分配给类型“String”.ts(2322)

但我的理解是

TE.sequenceArray
应该采用一组具有不同返回类型的函数,这些函数用
TaskEither
包装,并且它将按顺序返回一组响应。

javascript typescript functional-programming fp-ts
2个回答
2
投票

查看 文档

TE.sequenceArray
期望有一组具有相同正确类型的 TaskEithers。

export declare const sequenceArray: <A, E>(arr: readonly TaskEither<E, A>[]) =>
   TaskEither<E, readonly A[]>

您可以明确指定数组的类型为

Array<TE.TaskEither<Error, String | number>>
,并且它应该按预期工作。

pipe(
  [getName(), getAge()] as Array<TE.TaskEither<Error, String | number>>,
  TE.sequenceArray,
  // ...
);

然而,在调用

TE.chain
时解压这些值理论上可能是危险的。在
chain
调用中不能保证数组将有两个元素。正如所写的,它会,但类型检查器无法推断出这一点。
Do
符号可能更适合这些场景。


0
投票

@Souperman 的答案在这种情况下是正确的。

TE.sequenceArray
期望具有相同
TaskEithers
类型的
Right
数组。

如果我们要处理

TaskEither
的数组并且返回类型不同,那么我们可以使用
sequenceT

这是修改后的代码:

import * as TE from "fp-ts/TaskEither";
import { pipe } from "fp-ts/lib/function";
import { sequenceT } from "fp-ts/Apply";

function getName(): TE.TaskEither<Error, String> {
  return TE.right("John Doe");
}

function getAge(): TE.TaskEither<Error, number> {
  return TE.right(30);
}

export function seqArrayTest(): TE.TaskEither<Error, string> {
  return pipe(
    sequenceT(TE.ApplyPar)(getName(), getAge()),
    TE.chain(([name, age]) => {
      return TE.right(`Name: ${name}, Age: ${age}`);
    }),
    TE.mapLeft((e) => e)
  );
}

这里,

TE.chain(([name, age])
参数中
name
string
类型,
age
number
类型。响应顺序将基于调用顺序。

© www.soinside.com 2019 - 2024. All rights reserved.