result and pointFreeVersion must be refactored as well, fortunately you can use ReaderEither's monadic interface
// before constresult=pipe(E.right('foo'),E.chain(f),E.map(g),E.chain(h))constpointFreeVersion=flow(f,E.map(g),E.chain(h))// afterconstresult=pipe(RE.right('foo'),RE.chain(f),RE.map(g),RE.chain(b=>RE.fromEither(h(b))))constpointFreeVersion=flow(f,RE.map(g),RE.chain(b=>RE.fromEither(h(b))))
There's a benefit in using the monadic interface though: software is written in a uniform style, regardless of the effect.
I was just about to say it: I think main benefit is (ironically) readability - by saying explicitly Reader<Dependencies, string> you clearly communicate your intent (assuming others know the concept as well, of course 😄).
There's a benefit in using the monadic interface though: software is written in a uniform style, regardless of the effect.
You can think of
Readeras an effect, muck likeEitherorTask.Let's say you have the following snippet
and at some point you must refactor
ftoresultandpointFreeVersionmust be refactored as well, fortunately you can useReaderEither's monadic interfaceI was just about to say it: I think main benefit is (ironically) readability - by saying explicitly
Reader<Dependencies, string>you clearly communicate your intent (assuming others know the concept as well, of course 😄).That's right, you write programs by composing kleisli arrows
A -> M<B>, for some effectM.So
Reader(orReaderEither,ReaderTaskEither,Option,Either, etc...) is just one of the possible effects