Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support Reader monad in R.of(Function) #3452

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

semmel
Copy link
Contributor

@semmel semmel commented Apr 25, 2024

Ramda already supports binary curried functions as Reader monad:

  • map composes the mapping function and the Reader function
  • chain composes the chaining function in its first (value) argument with the Reader function and forwards the environment to the second argument.
  • ap is implemented so that liftR.converge

Still missing is the factory function of.

Although users can easily write their own,

const ofReader = a => x => a;
// or
const ofReader = a => always(a);

for convenience Ramda ought provide it as of(Function).

To illustrate a simple Reader function pipeline, I added some detailed examples to the documentation of R.of and R.chain.

If those examples are misleading I can remove or change them.
Furthermore, the R.of example is copied from @i-am-tom 's "Fantas, Eel, and Specification" article series which — sadly — seems to be offline now. I hope, we have his permission to use it here.

Copy link

Coverage
> ramda@0.29.1 coverage:summary
> BABEL_ENV=cjs nyc --reporter=text-summary mocha -- --reporter=min --require @babel/register

�[2J�[1;3H
1190 passing (897ms)


=============================== Coverage summary ===============================
Statements   : 94.04% ( 2477/2634 )
Branches     : 85.73% ( 967/1128 )
Functions    : 93.25% ( 553/593 )
Lines        : 94.32% ( 2323/2463 )
================================================================================

@Harris-Miller
Copy link
Contributor

Been a while since I've seen the "Fantas, Eel, and Specification" series. That brings me back

Tom's article demonstrates how by implementing typeclasses to Function lets you delegate function composition to those implementations. But there isn't anything you can't do there without pipe/compose/flow

It would be an oddly specific behavior to implement based on an implementation described in the article, rather than a general behavior, IMO. Besides, mutating the Function object or its prototype is a huge anti-pattern.

I find the use case of this to be extremely minimal, with very simple alternatives. R.of(Function, x) could be replaced by either R.always(x) or (_: any) => x to get the same effect. (As you show yourself in the description). And const ofReader = a => always(a); is just const ofReader = always. So you don't need a separate implementation, R.always already is your Function.of factory function

For Typescript, it's already difficult to type overloaded behavior like this to produce the correct return type, this overload just adds more complexity to an already complex typing of a function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants