Typescript 获取TaskEither数组中的第一个成功值

Typescript 获取TaskEither数组中的第一个成功值,typescript,functional-programming,monads,either,fp-ts,Typescript,Functional Programming,Monads,Either,Fp Ts,我对函数式编程比较陌生,对它也很陌生,所以我很难理解所提供的util函数。我目前正试图弄清楚如何将任务作为数组中的后备任务来处理 我有一个函数来获取一些id的数据,它返回Error或Success: declare function getData(id: number): TaskEither<Error, Success> 我尝试了类似的方法,但存在一些明显的问题(如下所述): 从'fp-ts/lib/Array'导入{map,sequence}; 从'fp ts/lib/t

我对函数式编程比较陌生,对它也很陌生,所以我很难理解所提供的util函数。我目前正试图弄清楚如何将
任务作为数组中的后备任务来处理

我有一个函数来获取一些
id
的数据,它返回
Error
Success

declare function getData(id: number): TaskEither<Error, Success>

我尝试了类似的方法,但存在一些明显的问题(如下所述):

从'fp-ts/lib/Array'导入{map,sequence};
从'fp ts/lib/taskorth'导入{map as maptaskorth}
const程序:taskstore
=管道(
[1, 2, 3, 4],
地图(getData),
sequence(taskother),//现在这将进入taskother
MapTaskOrther(成功=>成功[0])
);
这种方法的问题

  • 它在所有ID上运行
    getData
    ,第一次成功时不会短路
  • 如果任何
    getData
    s错误,则会显示错误。因此,如果
    getData(4)
    出错,即使
    getData(1)
    成功,整个
    程序也会出错
  • 它不会将错误收集到
    Error[]
  • 多亏了,我想出了一个解决办法

    为该util函数命名有助于提高可读性:

    import { TaskEither, taskEither, swap } from 'fp-ts/lib/TaskEither';
    import { sequence, map } from 'fp-ts/lib/Array';
    import { pipe } from 'fp-ts/lib/function';
    
    const firstRightOrLefts: <A, B>(taskEithers: TaskEither<A, B>[]) => TaskEither<A[], B>
        = taskEithers => pipe(
            taskEithers,
            map(swap),
            sequence(taskEither),
            swap,
        );
    
    从'fp-ts/lib/taskother'导入{taskother,taskother,swap};
    从'fp ts/lib/Array'导入{sequence,map};
    从'fp ts/lib/function'导入{pipe};
    常量firstRightOrLefts:(taskEithers:TaskOrther[])=>TaskOrther
    =taskEithers=>pipe(
    任务者,
    地图(交换),
    顺序(任选一项),
    交换
    );
    
    然后它可以这样使用:

    import { map } from 'fp-ts/lib/Array';
    
    const program: TaskEither<Error, Success>
      = pipe(
        [1, 2, 3, 4],
        map(getData),
        getFirstRightOrLefts, // <-- Woohoo!
      );
    
    从'fp ts/lib/Array'导入{map};
    const程序:taskstore
    =管道(
    [1, 2, 3, 4],
    地图(getData),
    
    getFirstRightOrLefts,//对于一个类似的问题,我找到了一个非常好的答案,但我很难理解函数编程中的所有抽象层。我会让更熟悉fp ts的人给出一个完整的答案,但我相信您必须实现自己的函数(或您自己的TaskOrder可遍历实例)如果您想保留Left=Error约定。如果您使用Right=Error,我认为您的代码满足您的要求。哦,这是一个很好的见解。它让我想到只需执行以下操作:…、映射(交换)、序列(TaskOrth),swap…我将尝试将其放入自己的函数中,这样它就可以合并为可读性。如果它有效,我将发布此问题的答案。好主意!
    import { TaskEither, taskEither, swap } from 'fp-ts/lib/TaskEither';
    import { sequence, map } from 'fp-ts/lib/Array';
    import { pipe } from 'fp-ts/lib/function';
    
    const firstRightOrLefts: <A, B>(taskEithers: TaskEither<A, B>[]) => TaskEither<A[], B>
        = taskEithers => pipe(
            taskEithers,
            map(swap),
            sequence(taskEither),
            swap,
        );
    
    import { map } from 'fp-ts/lib/Array';
    
    const program: TaskEither<Error, Success>
      = pipe(
        [1, 2, 3, 4],
        map(getData),
        getFirstRightOrLefts, // <-- Woohoo!
      );