I’m looking for something like Record.Do
with Record.bind
so I can do something like this
function getB: (a:A) => B
function getC: (b: B) => C
function getD: (c: C) => D
type Z = {
a: A,
b: B,
c: C,
d: D,
}
const getZ = (a: A): Z => pipe(
R.Do,
R.bind('a', () => a),
R.bind('b', () => getB(a)),
R.bind('c', (bindings) => getC(bindings.b)),
R.bind('d', (bindings) => getD(bindings.c)),
)
I basically want to construct an object of different types while retaining all the inner objects of different types before applying some transformations on them
Not sure how to go about achieving this. I don’t want to take my types to other domains like Option
, Either
, IO
; I feel like that just adds more code using O.some
(s) or E.right
(s) or IO.of
(s) for transformations that don’t error.
This is the closes I could get
const getZ = (a: A): Z => pipe(
IO.Do,
IO.bind('a', () => () => a),
IO.bind('b', () => () => getB(a)),
IO.bind('c', (bindings) => () => getC(bindings.b)),
IO.bind('d', (bindings) => () => getD(bindings.c)),
)()
CodePudding user response:
Why not just use the do notation on the Identity module? It's a type without any effects, so it should do what you want: https://gcanti.github.io/fp-ts/modules/Identity.ts.html#do-notation
CodePudding user response:
The imperative way to do this would be
const getZ = (a:A): Z => {
const b = getB(a)
const c = getC(b)
const d = getD(c)
return ({a, b, c, d})
}
More fp-ts, but still kinda imperative?
const getZ = (a: A): Z => pipe(
a,
(a) => ({ b: getB(a), a}),
(bindings) => ({ c: getC(bindings.b), ...bindings })
(bindings) => ({ d: getD(bindings.c), ...bindings })
)
Still looking for suggestions