typescript - 将类型化结构与 FP-TS 合并
问题描述
使用 FP-TS 时,我经常会发现结构体位于 aTask
或IO
. 我设法通过编写一个合并函数和单独的提升函数来解决这个问题,使其与Task
or一起使用IO
。有关更详细的说明,请参阅包含的代码示例。该代码有效,但我想知道我编写的自定义函数是否已经以某种形式或形式在 FP-TS 中可用。
import { deepStrictEqual as assertEqual } from 'assert'
import { IO, of, io, map } from 'fp-ts/lib/IO';
import { sequenceT } from 'fp-ts/lib/Apply';
import { pipe, tupled } from 'fp-ts/lib/function';
type Merge<A, B> = A & B
function merge<A, B>(a: A, b: B): Merge<A, B> {
return {...a, ...b}
}
type Foo = { foo: 123 }
type Bar = { bar: 456 }
type FooBar = Merge<Foo, Bar>;
const foo: Foo = { foo: 123 }
const bar: Bar = { bar: 456 }
const fooBar: FooBar = merge(foo, bar)
type IOLift<A, AS extends Array<any>, B> = (a: IO<A>, ...as: { [I in keyof AS]: IO<AS[I]> }) => IO<B>
function ioLift<A, AS extends Array<any>, B>(f: (a: A, ...as: AS) => B): IOLift<A, AS, B> {
return (...a) => pipe(
sequenceT(io)(...a),
map(tupled(f))
)
}
const ioMerge = ioLift(merge)
const ioFoo: IO<Foo> = of(foo)
const ioBar: IO<Bar> = of(bar)
const ioFooBar: IO<FooBar> = ioMerge(ioFoo, ioBar)
assertEqual(ioFooBar(), fooBar)
解决方案
可以使用Monoid
实例来合并相同类型的结构(请参阅 参考资料getStructMonoid
),但是您希望合并具有不同接口的结构,并且该操作没有类型类。但是,Object.assign
它等效于您的merge
函数,只是它最多可以合并四个参数(不止于此,您将any
在 TypeScript 中获得一个)。
至于ioLift
,没有什么与 in 等价的fp-ts
,但是您的sequenceT
+实现map
是将函数应用于某些参数的标准方法,当它们每个都恰好包装在某个应用函子中时,标准 for fp-ts
,也就是说,考虑到 TypeScript (请参阅@gcanti 的评论,了解为什么没有liftN
功能)。
鉴于sequenceT
+map
组合是多么微不足道,有人可能会争辩说它不符合Fairbairn ThresholdsequenceT
,这意味着每当您发现自己处于这种情况时,将+内联组合起来会更容易,而不是为遇到的每个应用函子map
编写专门的实用程序。liftWhatever
推荐阅读
- c++ - MATLAB 在 openCV 中的 imfinfo
- python - python pip 将库从 ~/.local 迁移到 /usr/local/lib
- html - 如何使用 HTML 从远程服务器打开文件
- json - 如何使用jq在`@name`为`dbUrl`的json数组中获取`@value`的值?
- node.js - 处理 Socket.io 中的服务器故障
- azure - 在 Angular 中使用 CORS
- websocket - Mqtt 连接为 aws IOT 预签名 URL 提供 403
- python - Pandas - 检查值是否在列中,如果没有则重新询问输入
- vba - Excel VBA在复制后将复选框链接到正确的单元格
- excel - 如何对每个类别求和