When using FP-TS I often end up with structs being inside a Task
or an IO
. I managed to solve the problem by writing a merge function and separate lift functions that make it work with Task
or IO
. See the included code example for a more detailed explanation. The code works but I'm wondering if the custom functions I wrote are already available in FP-TS in some shape or form.
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)