[英]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)
調用並使用fromEither
將Either
轉換為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.