-
Notifications
You must be signed in to change notification settings - Fork 376
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
Single source of truth for everything #158
Conversation
Basically, there is now one single source of truth, and `constructor` is not it.
59436c4
to
181555e
Compare
Also, note that this is based on #157, so it carries that commit. Here's that commit only. |
(By the way, I'm not that attached to this. If it gets rejected, I'm not that concerned.) |
|
||
3. `u.map(x => new Compose(x)).sequence(Compose.of)` is equivalent to | ||
`new Compose(u.sequence(F.of).map(v => v.sequence(G.of)))` for `Compose` defined below and any Applicatives `F` and `G` (composition) | ||
3. `u.map(compose.of).sequence(compose.of)` is equivalent to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something wrong here. new Compose
is intentionally not the same as Compose.of
see #141
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix that when I get home to compose.create
(the intended replacement method).
If we have |
Another ways to improve things in this area:
Maybe additionally to |
Note that the examples use plain objects for this reason. It's somewhat Lua-like.
I was aiming to remove the latter. (Check out the green parts.
See this comment by @davidchambers. That's why I removed references to constructor methods entirely. |
I still don't understand how one would use such API. Say someone gave me a type that compatible with FL; how do I create a value of that type? Or maybe FL don't have to support this use case (not sure). Btw why do we switch to plain objects and
That make sense. Seems like having it on prototype is essential. Btw, this PR is related to #88 (seems like it wasn't mentioned before). |
}; | ||
var compose = { | ||
of: function(x) { | ||
return {__proto__: compose, c}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you like a different method of setting the prototype? (Keep in mind, I'm not actually that deeply invested in this. I'm merely encouraging exploration.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not rely on the constructor
property as we currently do? We could write:
// Identity :: a -> Identity a
var Identity = function Identity(x) {
return {
constructor: {'fantasy-land/of': Identity},
'fantasy-land/chain': function(f) { return f(x); },
'fantasy-land/map': function(f) { return Identity(f(x)); },
// ...
value: x
};
};
The nice thing about this approach is it allows a prototype-based implementation:
// Identity :: a -> Identity a
var Identity = function Identity(x) {
if (!(this instanceof Identity)) return new Identity(x);
this.value = x;
};
// Identity.of :: a -> Identity a
Identity['fantasy-land/of'] = Identity;
// Identity#chain :: Identity a ~> (a -> Identity b) -> Identity b
Identity.prototype['fantasy-land/chain'] = function(f) { return f(this.value); };
// Identity#map :: Identity a ~> (a -> b) -> Identity b
Identity.prototype['fantasy-land/map'] = function(f) { return Identity(f(this.value)); };
// ...
I don't see a reason to use __proto__
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constructor: {'fantasy-land/of': Identity}
Identity['fantasy-land/of'] = Identity
But didn't we want to remove static method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway if we want to remove static method, I think we should simply remove static method from current implementations, without switching to simple objects or anything.
Given the immediate negative feedback (and the admitted non-idiomatic nature of it), I'm going to close it now. I think this was fully explored. |
#157 should still be looked at, though (it's just a series of bug fixes) |
|
||
m.empty() | ||
m.constructor.empty() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we all agree that this change is a good idea. I've opened #162 which makes this change only.
This stemmed from this short discussion. I think it would be a good idea to have a single source of truth for everything: the object itself (instead of an optional
constructor
method as well).Given other outstanding PRs and issues, I'd expect this would need to wait a bit even if accepted, because it messes with so much. Also, I refactored a few bits of code to not use classes unnecessarily.