标签: fp-ts

在 fp-ts 中链接一些异步任务,保留每个任务的结果

在 fp-ts 中,我试图将一些可能失败的异步任务链接在一起,TaskEither但我需要稍后在链中使用中间任务的结果。

在这个例子中:

const getFoo = (a: string): Promise<Foo> => {};
const getBar = (foo: Foo): Promise<Bar> => {};
const mkFooBar = (foo: Foo, bar: Bar): Promise<FooBar> => {};

const async main1: Promise<FooBar> => {
  const a = "a";
  const foo = await getFoo(a);
  const bar = await getBar(foo);
  const fooBar = await mkFooBar(foo, bar);

  return Promise.resolve(fooBar);
};

const main2: Promise<FooBar> => {
  const a = "a";

  return pipe(
    TE.tryCatch(() => getFoo(a), e => e),
    TE.chain(foo => …
Run Code Online (Sandbox Code Playgroud)

typescript fp-ts

10
推荐指数
1
解决办法
1574
查看次数

将任一&lt;E,A&gt; 数组转换为任一&lt;E,A[]&gt;(Scalaz 中的序列函数)

我仍在学习和使用 fp-ts 并且无法弄清楚这一点。

我有一个数组,Either<any, number>[]我想得到一个Either<any, number[]>.

我已经查看Apply.sequenceT了示例 sequenceToOption,它看起来很接近。

import { NumberFromString } from 'io-ts-types/lib/NumberFromString'
import { Either } from 'fp-ts/lib/Either'

const a:Either<any,number>[] = ['1','2','3'].map(NumberFromString.decode)

console.log(a)
// [ { _tag: 'Right', right: 1 },
//   { _tag: 'Right', right: 2 },
//   { _tag: 'Right', right: 3 } ]
Run Code Online (Sandbox Code Playgroud)

我想要一个错误或数字数组。

functional-programming fp-ts

6
推荐指数
1
解决办法
625
查看次数

从分页 API 延迟评估 fp-ts 中的递归流

我的目标是从 API 请求交易并将其存储到数据库中。响应是分页的,我想读取每一页并批量存储交易。

因此,对于一个请求/响应周期,我希望在获取下一批之前处理结果并将其存储到数据库中。

我如何在 fp-ts 中以惯用的方式执行此操作?我注入实际的 HTTP 获取调用,(url:string, init:RequestInit) => TE.TaskEither<Error, Response>以保持其可测试性。

到目前为止,我已经测试了 RxJS 和 fp-ts,即使我让它工作也有点复杂。

确实尝试了递归函数和生成器,但我没有成功地对其进行延迟评估。

是否有任何现有的 fp-ts 示例显示了一个延迟评估的流,其中每个元素都依赖于前一个元素?

recursion stream lazy-evaluation typescript fp-ts

6
推荐指数
1
解决办法
954
查看次数

如何在 FP-TS 中压平 TaskEither&lt;Error, Either&lt;Error, T&gt;&gt;

我是 fp-ts 新手。在处理组合 Either、IO 和 ... 时,我习惯使用 scala 进行理解。问题是,假设我们有带签名的函数

either(T): Either<Error, T>
ioEither(T): IOEither<Error, T>
taskEither(T): TaskEither<Error, T>
...
Run Code Online (Sandbox Code Playgroud)

我想把它们结合起来,我得到了一些类似的东西

pipe(T, taskEither, map(either)): TaskEither<Error, Either<Error, T>>
Run Code Online (Sandbox Code Playgroud)

哪个应该被压平。

如何组合T -> M<T>其中 M 是 IO 或 Task,以及T -> M<Error, T>M 是 Either、TaskEither 或 IOEither 的类型的函数,在过程中进行扁平化,就像使用 scala 进行理解一样?

typescript fp-ts

6
推荐指数
1
解决办法
1074
查看次数

如何在 FP-TS 中链接依赖的 TaskEither 操作

我是 FP-TS 的新手,仍然不太明白如何使用TaskEither. 我正在尝试异步读取文件,然后使用 yaml-parse-promise 解析结果字符串。

==编辑==

我使用文件的完整内容更新了代码以提供更多上下文,并应用了 MnZrK 提供的一些建议。抱歉,我对 FP-TS 还很陌生,并且仍在努力使类型匹配。

现在我的错误在于该行map(printConfig)

Argument of type '<E>(fa: TaskEither<E, AppConfig>) => TaskEither<E, AppConfig>' is not assignable to parameter of type '(a: TaskEither<unknown, AppConfig>) => Either<unknown, Task<any>>'.
  Type 'TaskEither<unknown, AppConfig>' is not assignable to type 'Either<unknown, Task<any>>'.
    Type 'TaskEither<unknown, AppConfig>' is missing the following properties from type 'Right<Task<any>>': _tag, rightts(2345)
Run Code Online (Sandbox Code Playgroud)

[我通过使用 TaskEither 中的 getOrElse 解决了这个问题,而不是来自 Either 库]

==编辑结束==

我已使用 IOEither 成功执行此操作,作为此项目的同步操作: https: //github.com/anotherhale/fp-ts_sync-example

我还查看了这里的示例代码: https ://gcanti.github.io/fp-ts/recipes/async.html

完整代码在这里: …

fp-ts

5
推荐指数
1
解决办法
6628
查看次数

在 fp-ts 中使用 TaskEither 和 fetch API

我想以某种方式将 Fetch API 包装在 fp-ts 中:

  1. 创建请求
  2. 检查状态
  3. 如果状态正常 - 返回 json
import * as TE from 'fp-ts/lib/TaskEither';
import * as E from 'fp-ts/lib/Either';
import { flow } from 'fp-ts/lib/function';
import { pipe } from 'fp-ts/lib/pipeable';

const safeGet = (url: string): TE.TaskEither<Error, Response> => TE.tryCatch(
  () => fetch(url),
  (reason) => new Error(String(reason))
);

const processResponce = flow(
  (x: Response): E.Either<Error, Response> => {
    return x.status === 200
      ? E.right(x)
      : E.left(Error(x.statusText))
  },
  TE.fromEither
);

export const httpGet = (url: string): …
Run Code Online (Sandbox Code Playgroud)

typescript fp-ts

5
推荐指数
1
解决办法
1648
查看次数

fp-ts 返回 Either[] 序列中的所有左值

我有一个字符串列表,string[]

我映射了一个返回的验证函数Either<Error, string>[]

我想要[Error[], string[]]所有验证错误和所有经过验证的字符串。

可以sequence(Either.Applicative)traverse(Either.Applicative)返回遇到的所有错误吗?我只收到Either<Error, string[]>,只是返回第一个错误。我是否需要编写自己的应用程序,带有合并左右半群的东西?

我可以通过更改为来获得所有map错误。reducefold

我还考虑反转验证,并运行两次。一个函数返回有效字符串,一个函数返回错误。

fp-ts

5
推荐指数
1
解决办法
1594
查看次数

FP-TS 分支(面向铁路的编程)

我在尝试使用 FP-TS 实现事物时不断遇到的一种模式是,当我的管道涉及到 TaskEither 的分支和合并分支时。

合并似乎工作得很好,因为我可以使用sequenceT创建数组并将它们通过管道传输到函数中,然后使用所有这些值。

似乎不太有效的是更复杂的依赖关系图,其中一个函数需要较早的项目,然后需要该函数的输出以及第一个任务的原始结果。

基本上像这样的函数签名(这可能不是 100% 正确的类型,但了解其要点):

function fetchDataA(): TaskEither<Error, TypeA> {
}

function fetchBBasedOnOutputOfA(a: TypeA): TaskEither<Error, TypeB> {
}

function fetchCBasedOnOutputOfAandB(a: TypeA, b: TypeB): TaskEither<Error, TypeC> {
}
Run Code Online (Sandbox Code Playgroud)

因为在管道中,你可以很好地为前两个作曲

pipe(
  fetchDataA(),
  TE.map(fetchBBasedOnOutputOfA)
)
Run Code Online (Sandbox Code Playgroud)

这个管道按预期返回 TaskEither<Error, TypeB> ,并且地图处理错误对我来说很好。

而要执行最后一个操作,我现在需要输入 TypeA 作为参数,但它不可用,因为它已传递到 B 中。

一种解决方案是让函数 B 同时输出 A 和 B,但这感觉不对,因为创建 B 的函数不必知道其他某个函数也需要 A。

另一种方法是创建某种中间函数来存储 A 的值,但在我看来,这破坏了使用 TaskEither 的全部意义,即我要抽象出所有错误类型并自动处理它。

我会有某种奇怪的功能:

async function buildC(a : TypeA): TaskEither<Error, TypeC> {
  const b = await fetchBBasedOnOutputOfA(a);
  // NOW DO MY OWN ERROR …
Run Code Online (Sandbox Code Playgroud)

typescript fp-ts

5
推荐指数
1
解决办法
997
查看次数

具有未知键的属性的 Io-ts 接口

我正在尝试创建以下的 io-ts 接口

我的接口.ts

export interface myInterface {
  [key:string]?: string | undefined | null
}
Run Code Online (Sandbox Code Playgroud)

我想把它变成 io-ts 等价物。最终目标是将它与另一个现有的 io-ts 接口结合起来

我的其他interface.ts

export const MyOtherInterfaceV = t.interface({
  requiredProp1: ValidString// custom type, checks string is populated
  requiredProp2: ValidString
  // All other fields marked as required
})

export type MyOtherInterface = t.TypeOf<typeof MyOtherInterfaceV>;
Run Code Online (Sandbox Code Playgroud)

这个想法是我需要一个类型来表示一个有效载荷,它有一些我们需要并且必须有效的字段,还有一些我们不知道并且可以是可选的。我们希望将这些组合起来以供稍后处理使用,最终存储在 dynamodb 中

types typescript fp-ts

4
推荐指数
2
解决办法
1390
查看次数

在 fp-ts 的管道中混合 Either 和 TaskEither

当没有一个函数是异步的时,我有以下程序可以正常工作。

interface Product {
  count: number
  pricePerItem: number
}

interface Tax {
  tax: number
}

interface Delivery {
  delivery: number
}

interface PTD { //ProductTaxDelivery
  p: Product
  t: number
  d: number
}

function getProduct(): Either<Error, Product> {
  return E.right({ count: 10, pricePerItem: 5 })
}

function getTax(p: Product): Either<Error, number> {
  return E.right(p.pricePerItem * p.count * 0.085)
}

function getDelivery(p: Product): Either<Error, number> {
  return  E.right(p.count * 0.05)
  //or maybe return E.left(Error('some error in delivery happened'))
}
function run(): Either<Error, …
Run Code Online (Sandbox Code Playgroud)

functional-programming fp-ts

4
推荐指数
1
解决办法
3340
查看次数