对于返回Either不同值,我有两个验证函数。 如果它们中的一个具有left值,我想抛出一个异常,如果两个都right ,则不执行任何操作。 我以前从未使用过fp-ts,也无法弄清楚如何正确组合左结果。 我当前的解决方案有效,但感觉不到我使用的正确。

import { Either, left, right, isLeft, getOrElse } from 'fp-ts/lib/Either';

function validateMonth( m: Month ): Either<Error, Month> {
   return m.isInRange() ? right(m) : left(new Error('Month must be in range!'));
}

function validateYear( y: Year ): Either<Error, Year> {
   return year.isBefore(2038) ? right(y) : left(new Error('Year must be before 2038!'));
}

function throwingValidator(m: Month, y: Year): void {
 // todo: Refactor to get rid of intermediate variables,
 // combining results of validateMonth and validateYear into a type
 // of Either<Error, Unit>
 const monthResult = validateMonth( month );
 const yearResult = validateYear( year );
 const throwOnError = (e: Error) => { throw e; };
 if ( isLeft( monthResult ) ) { getOrElse(throwOnError)(monthResult); }
 if ( isLeft( yearResult ) ) { getOrElse(throwOnError)(yearResult); }
}

我已经在https://dev.to/gcanti/getting-started-with-fp-ts-two-vs-validation-5eja中阅读了介绍,但是该代码与我想要的完全相反:我没有关心验证后的输入值,只想返回发生的第一个错误。

#1楼 票数:1

您可能正在寻找类似的东西

const toPromise = fold(e => Promise.reject(e), r => Promise.resolve(r));

Promise.all([
    toPromise(validateMonth(month)),
    toPromise(validateYear(year)),
]).then(([validMonth, validYear]) => {
    return …
});

或更实用的方式

toPromise(ap(ap(of(validMonth => validYear => {
    return …
}), validateMonth(month)), validateYear(year)))

您还可以使用array.sequence和之后的Promise.allarray.sequence toPromise

#2楼 票数:1 已采纳

忽略throwingValidator和一般的throwing(这首先会破坏使用fp-ts的目的),而仅关注此特定请求:

重构以除去中间变量,将validateMonth和validateYear的结果组合为Either类型

您可能正在寻找:

const monthAndYearResult: Either<
  Error,
  { month: Month, year: Year }
> = sequenceS(either)({
  month: validateMonth(month),
  year: validateYear(year)
})

“序列”荷兰国际集团中一般需要的一个实例Traversable (结构体{ year, month }在这种情况下)和的一个实例Applicativeeither在这种情况下),并且语义聚合不同的独立的计算一起的那些。

如果你明确要忽略的结果,通常是_ -suffix替代提供了实现这个目标,但它并不像现在在fp-ts V2。

因此,要获取Either<Error, void>您可以诉诸:

const result = pipe(
  sequenceS(E.either)({ month: validateMonth(month), year: validateYear(year) }),
  E.map(constVoid)
)

请注意, sequenceS只是可能的选项之一,您可以使用sequenceTarray.sequence获得类似的结果,例如:

pipe(
  sequenceT(either)([validateMonth(month), validateYear(year)]),
  E.map(constVoid)
)

  ask by chiborg translate from so

未解决问题?本站智能推荐:

2回复

将联合类型转换为 fp-ts 中的任一类型

在打字稿中,如何将联合类型A|B转换为fp-ts的Either<A,B> ? 这感觉很自然,必须有一种很好的方法来做到这一点。
1回复

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

我对函数式编程比较陌生,对fp-ts也很陌生,所以我很难围绕提供的 util 函数。 我目前正试图弄清楚如何将TaskEither作为数组中的后备处理。 我有一个函数来获取某些id数据,它返回Error或Success : 我想要的是一个函数,它将遍历一些id数组(例如[1, 2, 3, 4]
1回复

如何在 FP 中管理 monad,特别是在 fp-ts 中

我对函数式编程和特别是fp-ts库很fp-ts 。 我的问题包括两部分: 我看到了一种将 Monads 从一种类型转换为另一种类型的模式,例如从Task到IO ,反之亦然,我们如何管理这种情况,我们应该始终保持在一个类型上,还是应该随着链的继续而改变? 如何简单地使打字稿遵循这些从一个到
2回复

如何折叠两种不同的类型? FP-TS

我正在用 FP-TS 学习 FP,但我遇到了一个障碍: 我的存储库中有以下功能: // this is the repository export const findBook = (id: string) => TaskEither<Error, Option<ParsedBo
2回复

从 fp-ts 中的项目数组中删除选项

假设我有以下类型: 以及以下错误处理助手: 然后我创建一个像这样的函数: 这一切都编译得很好,但我真正想要的是返回一个没有过滤掉的数组,如果没有则引发适当的错误! 幼稚的做法是将正确路径的返回更改为: 但这不会编译,抛出以下错误: 如何应用这种过滤?
1回复

将数组转换为对象的正确 fp-ts 方法

我是函数式编程的新手,但想学习最佳实践。 将数组转换为对象的正确 fp-ts 方法是什么? (items: Item[], keyGetter: (i: Item) => Key) => Record<Key, Item> 到目前为止,我使用自己的 not fp-ts
1回复

fp-ts 在 mapLeft 中调用异步函数

我是 fp-ts 的新手,所以请帮助我解决我的问题:我需要使用异步函数在不同级别多次记录相同的错误。 这是我的示例代码: 我正在使用mapLeft来做到这一点,但它不起作用。 我需要做什么才能在err2中获得错误的值(err1)而不是未决的承诺?
1回复

如何从 ReaderEither [] 给读者在 fp-ts 中?

在 fp-ts 中,我如何从ReaderEither<R, E, A>[]到ReaderEither<R, E[], A[]> ? 本质上,我想将ReaderEither实例数组转换为单个ReaderEither实例。 我试过寻找答案,但运气不佳。 我是函数式编程和 fp-