Lodash 或 Ramda `cond` 的 FP-TS 等价物?

标签 fp-ts

试图弄清楚如何使用 fp-ts 对多个案例进行建模。不确定我对这个操作的心理模型是否应该在 fp-ts 中有所不同,我是否找不到合适的函数来使用,或者这样的函数不存在。

供引用,https://ramdajs.com/docs/#cond (Lodash 中相同的签名+行为)

示例案例是加载/加载状态,或在枚举上拆分案例。例如,

enum abcd {a,b,c,d}

const getCaseResult = cond([
  [is(a), getResultA],
  [is(b), getResultB],
  [is(c), getResultC],
  [is(d), getResultD],
])

getCaseResult('a') // returns result of getResultA('a')

最佳答案

我深入研究了 Ramda 的类型定义,因为我很好奇如果实际上谓词函数是类型保护,它们是如何处理类型的。事实证明他们没有使用类型保护来缩小类型。 See DefinitelyTyped Code .

顺便说一句,那里的评论实际上使他们给出的类型定义无效:

If none of the predicates matches, fn returns undefined.

但是类型声明它返回一个 R 而不是 R |未定义。我尝试使用 fp-ts 实用程序实现具有等效类型的 cond,因为正如一些评论者指出的那样,它看起来不像 fp-ts 有一个内置的等价于 cond。

这样的事情对你有用吗?

import { reduce } from "fp-ts/lib/Array";
import { alt, some, none, fold, Option } from "fp-ts/Option";
import { pipe } from "fp-ts/lib/function";

type CondPair<T extends any[], R> = [
  (...args: T) => boolean,
  (...args: T) => R
];
const cond = <T extends any[], R>(pairs: Array<CondPair<T, R>>) => (
  ...args: T
): R | undefined =>
  pipe(
    pairs,
    reduce(
      none,
      (prev: Option<R>, [pred, res]: CondPair<T, R>): Option<R> =>
        pipe(
          prev,
          alt(() => (pred(...args) ? some(res(...args)) : none))
        )
    ),
    fold(
      () => undefined,
      (r) => r
    )
  );

enum abcd {
  a,
  b,
  c,
  d
}

const is = <T>(t: T) => (x: unknown) => t === x;

function isResultA(a: abcd) {
  return 1;
}
function isResultB(b: abcd) {
  return 2;
}
function isResultC(c: abcd) {
  return 3;
}
function isResultD(d: abcd) {
  return 4;
}

const getCaseResult = cond([
  [is(abcd.a), isResultA],
  [is(abcd.b), isResultB],
  [is(abcd.c), isResultC],
  [is(abcd.d), isResultD]
]);

for (let x of [abcd.a, abcd.b, abcd.c, abcd.d]) {
  console.log(getCaseResult(x));
} // Logs 1, 2, 3, 4 respectively

关于Lodash 或 Ramda `cond` 的 FP-TS 等价物?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68569750/

相关文章:

typescript - 如何将 Either 与异步函数一起使用

typescript - Option 和 OptionT 有什么区别?

typescript - 如何在io-ts中定义混合数组?

typescript - 如何将静态类型的函数记录应用于 typescript 中的参数

typescript - fp-ts/typescript 避免嵌套管道

typescript - 来自 fp-ts 和 URI 的 typescript 中更高种类的类型

javascript - 将类型 `(env) => (args) => TaskEither` 转换为 ReaderTaskEither

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

typescript - 并行运行一组 TaskEithers,但如果 1 个或多个任务失败则继续

typescript :如何 kleisli compose (monadic compose) Promise monad using fp-ts