Help understanding Reader Monad #1554
-
Trying to understand the reader monad. I've been messing with it for hours, have read multiple articles, and even have working code, but the types break. I'd super appreciate help understanding what's happening. Cross-posting with examples here: https://stackoverflow.com/questions/68641581/how-to-make-a-single-level-pipe-flow-with-the-fp-ts-reader-monad. Help in either place appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
The type definition for interface Reader<R, A> {
(r: R): A
}
The type definition for interface IO<A> {
(): A
}
The signature for export declare const bind: <N extends string, A, E, B>(
name: Exclude<N, keyof A>,
f: (a: A) => Reader<E, B>
) => (ma: Reader<E, A>) => Reader<E, { readonly [K in N | keyof A]: K extends keyof A ? A[K] : B }>
export declare function flow<A extends ReadonlyArray<unknown>, B, C>(
ab: (...a: A) => B,
bc: (b: B) => C
): (...a: A) => C So, looking at the following code: flow(
bind('foo', ({ account }: Env) => of('foo' + account)),
apS('bar', of('bar')),
) The type being returned by that (ma: Reader<unknown, Env>) => Reader<unknown, Env & { foo: string, bar: string }> because the type returned by One way this problem may be tackled is like so: import * as R from "fp-ts/Reader";
import * as IO from "fp-ts/IO";
import { pipe } from "fp-ts/function";
interface Env {
account: string;
region: string;
}
const getEnv: IO.IO<Env> = () => ({ account: "123", region: "456" });
/**
* In this case, it is best for the input of the `Reader` to not be wrapped in a computation,
* such as in the example of `Reader<IO<Env>, ...>`. Having a `Reader<Env, ...>`
* makes it easier to compose and use.
*/
const reader = pipe(
// Read the context (returns `Reader<Env, Env>`)
R.ask<Env>(),
R.bind("foo", ({ account }) => R.of("foo" + account)),
R.apS("bar", R.of("bar"))
);
/**
* console.log(pipe(getEnv, IO.map((env) => reader(env)))());
*/
console.log(pipe(getEnv, IO.map(reader))()); |
Beta Was this translation helpful? Give feedback.
-
this article from @gcanti help me alot, |
Beta Was this translation helpful? Give feedback.
The type definition for
Reader
isReader
is a function fromR
toA
.The type definition for
IO
isIO
is a function from no input toA
. In some contexts, it may also be thought of asReader<unknown, A>
.The signature for
Reader
'sbind
isbind
takes a name and a function from the output of theReader
to a new value and returns a function from aReader
to aReader
with that new value assigned to the name in an object.…