-
-
Notifications
You must be signed in to change notification settings - Fork 20
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
add apFirst and apSecond #11
add apFirst and apSecond #11
Conversation
@@ -50,7 +50,7 @@ This project provides: | |||
|
|||
## API | |||
|
|||
<h4 name="TypeClass"><code><a href="https://github.com/sanctuary-js/sanctuary-type-classes/blob/v1.0.0/index.js#L105">TypeClass :: (String, Array TypeClass, a -> Boolean) -> TypeClass</a></code></h4> | |||
<h4 name="TypeClass"><code><a href="https://github.com/sanctuary-js/sanctuary-type-classes/blob/v1.0.0/index.js#L112">TypeClass :: (String, Array TypeClass, a -> Boolean) -> TypeClass</a></code></h4> |
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.
As mentioned in the CONTRIBUTING.md, it's not necessary to update README.md manually. ;)
@@ -88,6 +88,13 @@ | |||
// identity :: a -> a | |||
var identity = function(x) { return x; }; | |||
|
|||
// kCombinator :: a -> b -> a | |||
var kCombinator = function(x) { |
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.
Let's name this constant
for consistency with identity
.
@@ -1056,6 +1063,42 @@ | |||
return ap(ap(map(f, x), y), z); | |||
}; | |||
|
|||
//# apFirst :: Apply f => f a -> f b -> f a |
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.
Since this function is not curried, the signature should be Apply f => (f a, f b) -> f a
.
//# apFirst :: Apply f => f a -> f b -> f a | ||
//. | ||
//. Combine two effectful actions, keeping only the result of the first. | ||
//. Equivalent to Haskell's <* function. |
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.
Let's write (<*)
rather than <*
.
//. > apFirst([1, 2], [3, 4]) | ||
//. [1, 1, 2, 2] | ||
//. | ||
//. ```javascript |
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.
This needs to move up a few lines.
62f1e98
to
787980b
Compare
Thanks for the review @davidchambers . I've updated the PR for all your comments. And reverted the changes to README.md. Please let me know they are good :) |
@@ -88,6 +88,13 @@ | |||
// identity :: a -> a | |||
var identity = function(x) { return x; }; | |||
|
|||
// constant :: a -> b -> a | |||
var constant = function(x) { |
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.
Please add one more space between //
and constant
to align the function name in type line with the identifier on the following line. :)
Also, for lack of a better system the helper functions are defined in alphabetical order, so constant
should be defined before identity
.
//# apFirst :: Apply f => (f a, f b) -> f a | ||
//. | ||
//. Combine two effectful actions, keeping only the result of the first. | ||
//. Equivalent to Haskell's (<*) function. |
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.
Let's wrap the function name in backticks so it will be rendered as "(<*)
" rather than "(<*)".
787980b
to
17eef50
Compare
Good advices! Just updated, please take a look again, thanks @davidchambers |
Thanks very much for submitting this pull request, @zhangchiqing, and for updating it quickly in response to my suggestions. I'd like to leave this open for a day or two while we decide on the most appropriate names, but otherwise this looks ready to merge. :) |
Good to know :) Yes, I agree. Please let me know if we need to rename them. Thanks again for the code review. |
@scott-christopher I agree left/right could be confusing because of Either type, in that case I think |
Are you happy with this pull request as it stands, @safareli? |
I would like if we use |
They're essentially binary operators, aren't they? I think of the blanks in |
Agree! |
@@ -1272,6 +1315,8 @@ | |||
ap: ap, | |||
lift2: lift2, | |||
lift3: lift3, | |||
apFirst: apFirst, | |||
apSecond: apSecond, |
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.
One last thing: I think apFirst
and apSecond
should come between ap
and lift
. Could you move the definitions, the exports, and the tests?
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.
Do you mean var apFirst = ...
should be placed between var ap = ...
and var lift2 = ...
?
Can I ask what's the idea behind it :)
The thing is I implemented apFirst
and apSecond
using lift2
. If I move the definition above lift2
, it looks like apFirst
is using a function (lift2)
that is not defined yet.
Or I can place apFirst
between ap
and lift2
and refactor apFirst
in terms of ap
and map
as below, since ap
and map
are both defined above apFirst
and apSecond
.
var apFirst = function apFirst(x, y) {
return ap(map(constant, x), y);
};
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 think you can still have access to lift2 if you move apFirst up, because of js hoisting
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 think you can still have access to lift2 if you move apFirst up
Yeah, I agree. Syntax-wise it would work.
Do you think one day 'lift2` will support currying? In which case:
var apFirst = lift2(constant);
Won't work, because lift2
is not defined yet.
Also I'm going to add apFirst
and apSecond
to sanctuary.js
after this PR has been merged. Since lift2
is curried in sanctuary.js
, I can implement them like this var apFirst = S.lift2(S.I);
, but I can't place them above S.lift2
.
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.
Good point, @zhangchiqing. The location you chose is perfect! I'll merge this when I get home. :)
Thanks again for this nice contribution, @zhangchiqing. Don't worry about creating a Sanctuary pull request; I will update sanctuary-js/sanctuary#216 to include 🌳 |
Awesome! I'm more than happy to contribute :) |
One more question: Will the README.md be updated with the new functions once this PR gets merged? Should we run |
readme is updated when version is bumped |
@zhangchiqing, see sanctuary-js/sanctuary-set#1 (comment) if you'd like to know how and when the readme is updated. :) |
Hi @davidchambers ,
I just moved the changes from sanctuary-js/sanctuary#270 (comment) to here.
I didn't change the function names, as they are still in discussion.
Please review.
I will create another PR to sanctuary-js/sanctuary#216 once this PR has been merged.