繁体   English   中英

如何避免在fp-ts中嵌套Monad或优雅地处理它们?

[英]How do I avoid nested Monads in fp-ts or deal with them elegantly?

我有一个代码序列,需要执行以下步骤(伪代码):

  jobsRepository.findById // <-- this returns a TaskEither
  jobs.openJob // <-- jobs.openJob returns an Either
  jobsRepository.update // <-- this returns another TaskEither
  createJobOpenedEvent // simple function that returns an IJobOpenedEvent
                       // given an IOpenJob

如果将这些步骤映射/链接在一起,最终会得到类似TaskEither<IError, Either<IError, TaskEither<IError, IOpenJob>>>这样的TaskEither<IError, Either<IError, TaskEither<IError, IOpenJob>>>这显然有点尴尬。

我当前将所有这些扁平化为简单TaskEither<IError, IJobOpenedEvent>类型的解决方案如下所示(实际代码):

import { flatten } from "fp-ts/lib/Chain";
import { Either, either, left, right } from "fp-ts/lib/Either";
import {
  fromEither,
  TaskEither,
  taskEither,
  tryCatch,
} from "fp-ts/lib/TaskEither";

const createJobOpenedEvent = (openJob: jobs.IOpenJob): IJobOpenedEvent => ({
  name: "jobOpened",
  payload: openJob,
});

export const openJobHandler = (
  command: IOpenJobCommand
): TaskEither<IError, IJobOpenedEvent> =>
  flatten(taskEither)(
    flatten(taskEither)(
      jobsRepository
        .findById(command.jobId) // <-- this returns a TaskEither<IError, IJob>
        .map(jobs.openJob) // <-- jobs.openJob returns an Either<IError, IOpenJob>
        .map(fromEither)
        .map(jobsRepository.update) // <-- this returns a TaskEither<IError,IOpenJob>
    )
  ).map(createJobOpenedEvent);


我的问题是-是否有更好的方法来处理此嵌套? 我感觉自己做错了,因为我不熟悉函数式编程,也不了解所有理论。 将所有嵌套的flatten(taskEither)调用并使用fromEitherEither转换为TaskEither对我来说似乎很糟糕。

任何帮助深表感谢!

感谢Bergi的评论,我能够使用chain而不是map找到以下解决方案:

export const openJobHandler = (
  command: IOpenJobCommand
): TaskEither<IError, IJobOpenedEvent> =>
  jobsRepository
    .findById(command.jobId)
    .map(jobs.openJob)
    .chain(fromEither)
    .chain(jobsRepository.update)
    .map(createJobOpenedEvent)

暂无
暂无

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

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