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

标签 typescript functional-programming fp-ts

如何将两个 kleisli 箭头(函数)f:A -> Promise Bg: B -> Promise C 组合成 h:A -> 使用 fp-ts promise C

我熟悉 Haskell,所以我会这样问:>=>=>(fish operator)的等价物是什么?

最佳答案

promise 由 Task 表示或 TaskEither fp-ts 中的单子(monad),这是异步计算。 TaskEither另外对故障进行建模并且与 Task<Either<...>> 相同.

Kleisli 箭头可以通过 chain 组成monad 的操作和 flow (管道运算符(operator))。结果类似于 >=> 的应用程序Haskell 中的运算符。

让我们用 TaskEither 做一个例子:
const f = (a: A): Promise<B> => Promise.resolve(42);
const g = (b: B): Promise<C> => Promise.resolve(true);
转换函数返回 Promise返回的人 TaskEither使用 tryCatchK 1:
import * as TE from "fp-ts/lib/TaskEither";
const fK = TE.tryCatchK(f, identity); // (a: A) => TE.TaskEither<unknown, B>
const gK = TE.tryCatchK(g, identity); // (b: B) => TE.TaskEither<unknown, C>
组成两者:
const piped = flow(fK, TE.chain(gK)); // (a: A) => TE.TaskEither<unknown, C>

这是 Codesandbox 的复制粘贴 block :

// you could also write:
// import { taskEither as TE } from "fp-ts";
import * as TE from "fp-ts/lib/TaskEither";
// you could also write:
// import {pipeable as P} from "fp-ts"; P.pipe(...)
import { flow, identity, pipe } from "fp-ts/lib/function";
import * as T from "fp-ts/lib/Task";

type A = "A";
type B = "B";
type C = "C";
const f = (a: A): Promise<B> => Promise.resolve("B");
const g = (b: B): Promise<C> => Promise.resolve("C");

// Alternative to `identity`: use `toError` in fp-ts/lib/Either
const fK = TE.tryCatchK(f, identity);
const gK = TE.tryCatchK(g, identity);

const piped = flow(fK, TE.chain(gK));

const effect = pipe(
  "A",
  piped,
  TE.fold(
    (err) =>
      T.fromIO(() => {
        console.log(err);
      }),
    (c) =>
      T.fromIO(() => {
        console.log(c);
      })
  )
);

effect();

为什么没有 promise ?

JavaScript Promise 不遵守 monadic API ,例如它们是 eagerly computed 2。在函数式编程中,副作用会被尽可能地延迟,所以我们需要使用 Task 形式的兼容包装器。或 TaskEither .


1 identity只是在失败情况下转发错误。您也可以使用 toError .
2 Incorporate monads and category theory #94如果您对历史原因感兴趣,值得一读。

关于 typescript :如何 kleisli compose (monadic compose) Promise monad using fp-ts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64514213/

相关文章:

typescript - 除非提供 '--module' 标志,否则无法编译模块

swift - 如何在 swift 中编写 not/negate 高阶函数?

functional-programming - 在 map 内部使用 if 时如何处理 "if may be missing an else clause"?

Javascript/Typescript 从函数内部调用外部函数

javascript - AngularJS类类型检查解决方案

typescript - 是否可以在 TypeScript 中实现函数接口(interface)?

python - 函数式 python——为什么这些生成器中只有一个需要 list() 才能工作?

typescript - 使用 fp-ts 重写一个用记录器包装的小函数

javascript - 如何缩小从 fp-ts R.lookup 推断的选项类型