-
-
Notifications
You must be signed in to change notification settings - Fork 95
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
Added function S.on #282
Added function S.on #282
Conversation
Thanks for the pull request, @Bradcomp! There are a few minor things on which I will comment, but overall it looks very good. :) |
@@ -713,6 +713,25 @@ | |||
[$.Function, a, b, c, d], | |||
lift3); | |||
|
|||
//# on :: (b -> b -> c) -> (a -> b) -> a -> a -> 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.
We must decide whether the type of the first argument should be b -> b -> c
or (b, b) -> c
. Currently the type signature and the implementation contradict each other.
There are a handful of higher-order functions for which we provide both forms. In each case S.<name>
takes a curried function while S.<name>_
takes an uncurried function. We could provide both S.on
and S.on_
, but S.on
should take a b -> b -> c
function regardless.
|
||
it('should pass the last two arguments through the modifying function into the converging function', function() { | ||
eq(S.on(S.max, S.prop('x'), {x: 3, y: 5}, {x: 5, y: 3}), 5); | ||
eq(S.on(S.concat, S.reverse)([1, 2, 3], [4, 5, 6]), [3, 2, 1, 6, 5, 4]); |
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.
def('on', | ||
{}, | ||
[$.Function, $.Function, a, a, c], | ||
on); |
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.
It would be fine to have this on one line:
S.on = def('on', {}, [$.Function, $.Function, a, a, c], on);
//. results through the binary function. | ||
//. | ||
//. ```javascript | ||
//. S.on(S.concat, S.reverse, [1, 2, 3], [4, 5, 6]) |
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 line is missing the >
which indicates a doctest input line.
{}, | ||
[$.Function, $.Function, a, a, c], | ||
on); | ||
|
||
//. ### Composition |
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.
Perhaps on
should live in the Composition section rather than the Function section. When I consider what it does I imagine something like this:
x y
| |
| |
| |
| |
| |
+-----+ +-----+
| g | | g |
+-----+ +-----+
\ /
\ /
g(x) \ / g(y)
\ /
\ /
+-----+
| f |
+-----+
|
|
|
|
|
f(g(x))(g(y))
|
||
var eq = require('./internal/eq'); | ||
|
||
describe('on', 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.
Nit: Two empty lines after imports, please.
|
||
describe('on', function() { | ||
|
||
it('has an arity of four', 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.
For consistency, let's write 'is a quaternary function'
.
//. | ||
//. Takes a binary function, a unary function, and two values. Returns the | ||
//. result of applying the unary function to each value, then passing the | ||
//. results through the binary 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.
"Passing through" doesn't sound right to me for some reason. Combinators are sometimes best explained by their definitions. We could write something along these lines:
Takes a binary function f
, a unary function g
, and two values x
and y
. Returns f(g(x))(g(y))
.
var rem_ = require('./internal/rem_'); | ||
|
||
|
||
describe('on', 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.
s/on/on_/
|
||
|
||
describe('on', 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 include an 'is a quaternary function'
block for this function too.
eq(S.on.length, 4); | ||
}); | ||
|
||
it('should pass the last two arguments through the modifying function into the converging function', 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.
Nit: I prefer it does X to it should do X. In this case, it passes the last two arguments…
Thanks for the updates. Providing both One downside of my preference for rebasing is that I don't receive notifications when pull requests are updated. Please leave a comment after making the second round of changes to let me know I should take one last look. :) |
Thanks for your feedback! I've updated the PR based on your comments. |
//# on :: (b -> b -> c) -> (a -> b) -> a -> a -> c | ||
//. | ||
//. Takes a binary function `f`, a unary function `g`, and two | ||
//. values `x` and `y`. Returns f(g(x))(g(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.
Let's wrap f(g(x))(g(y))
in backticks.
I'll merge this once you've made the final copy tweak. I appreciate your patience. :) |
Alright! I think we should be good to go. Thanks for you time in looking this over and considering it! |
🌳 |
|
Closes #281