Closed samhh closed 2 years ago
Is this what you'd expect?
export const runReader: <R, A>(r: R) => (reader: Reader<R, A>) => A =
(r) => (reader) =>
reader(r)
If I were to write it just like the Haskell implementation I think it would likely be a bit annoying to use in a pipe e.g with my proposed solution you could
type Env = { env: string }
declare const myReader: RTE.ReaderTaskEither<Env, Error, string>
const getString: TE.TaskEither<Error, string> = pipe(
myReader,
runReader({env: 'hello'})
)
But if I were to reverse the order of r
and reader
to be closer to the Haskell's signature you'd end up having to do something like
type Env = { env: string }
declare const myReader: RTE.ReaderTaskEither<Env, Error, string>
const getString: TE.TaskEither<Error, string> = pipe(
myReader,
_ => runReader(_)({env: 'hello'})
)
I don't really know much about of Haskell so I'm sorry if I understood the signature incorrectly.
Also, wouldn't it also make sense to introduce a runReaderTask
function that would runrunReader
as well as Task.execute
? 😄
That first runReader
is it, although r => reader => reader(r)
could be replaced with apply
. The purpose is to provide a centralised way to run a reader that hides the implementation detail that it's just a function.
Yep, per-monad transformer variants make sense. I wouldn't run execute
though, that's really for the very edges of the application. Example:
declare const runReaderTask: <R>(r: R) => <A>(m: ReaderTask<R, A>) => Task<A>
That could probably also be just apply
.
Alias of
apply
.https://hackage.haskell.org/package/transformers-0.6.0.4/docs/Control-Monad-Trans-Reader.html#v:runReader