-
-
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
Curry: Add functions curry2 through curry5 #289
Conversation
Thanks for the pull request, @laduke! It's exciting to have received pull requests from three new code contributors in the past week! I edited this pull request's description to include the substring |
We simply haven't needed this so many unary type variables before, but we're free to define
The readme gets updated automatically at release time. See sanctuary-js/sanctuary-set#1 (comment) if you're interested in the details. |
//# curry2 :: ((a, b) -> c) -> a -> b -> c | ||
//. | ||
//. Curry a binary function. | ||
//. ```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.
Please include an "empty" (//.
) line between the description and the code block.
//. ```javascript | ||
//. > todo | ||
//. todo | ||
//. ``` |
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.
Here's an example which does not seem contrived:
> global.toUrl = S.curry5((protocol, creds, hostname, port, pathname) =>
. protocol + '//' +
. S.maybe('', _ => _.username + ':' + _.password + '@', creds) +
. hostname +
. S.maybe('', S.concat(':'), port) +
. pathname
. )
> toUrl('https:')(S.Nothing)('example.com')(S.Just('443'))('/foo/bar')
'https://example.com:443/foo/bar'
> toUrl('https:', S.Nothing, 'example.com', S.Just('443'), '/foo/bar')
'https://example.com:443/foo/bar'
eq(typeof S.curry2, 'function'); | ||
eq(S.curry2.length, 3); | ||
|
||
var curried = S.curry2(source); |
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 define the function here:
var curried = S.curry2(function(x, y) { return x * y; });
@@ -632,6 +632,54 @@ | |||
|
|||
//. ### Function | |||
|
|||
//# curry2 :: ((a, b) -> c) -> a -> b -> c | |||
//. | |||
//. Curry a 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.
I like these short descriptions. For consistency we should use Curries a binary function. Also, we could be more specific about which function gets curried:
Curries the given binary function.
Thank you for your patience @davidchambers. |
//. > global.createRect = S.curry4((x, y, width, height) => ( | ||
//. . {x, y, width, height} | ||
//. . ) | ||
//. . ) |
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'd prefer this formatting:
> global.createRect = S.curry4((x, y, width, height) =>
. ({x, y, width, height})
. )
//. | ||
//. ```javascript | ||
//. > R.map(S.curry2(Math.pow, 10), [1, 2, 3]) | ||
//. [ 10, 100, 1000 ] |
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 use [10, 100, 1000]
here (without the extra spaces).
//. createRect | ||
//. | ||
//. > createRect(0)(0)(10)(10) | ||
//. { x: 0, y: 0, width: 10, height: 10 } |
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 use {x: 0, y: 0, width: 10, height: 10}
here (without the extra spaces).
I've become spoiled by jsfmt. Sorry about those. |
eq(curried(1, 2, 3, 4, 5), 15); | ||
eq(curried(1)(2)(3)(4)(5), 15); | ||
eq(curried(1, 2)(3, 4)(5), 15); | ||
eq(curried(1)(2, 3)(4, 5), 15); |
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 might as well enumerate all the combinations. I wrote a script to make this easier:
'use strict';
const pow2 = exp => Math.pow(2, exp);
const generateAssertions = (xs, f) => {
const l = xs.length;
return Array(pow2(l - 1)).join('x').split('x').reduce((s, _, m) =>
xs.reduce((s, x, n) =>
`${s}${x}${n === l - 1 ? '' : m % pow2(l - n - 1) >= pow2(l - n - 2) ? ')(' : ', '}`,
`${s} eq(curried(`
) + `), ${f(...xs)});\n`,
''
);
};
process.stdout.write(generateAssertions([1, 2, 3, 4, 5], (v, w, x, y, z) => v + w + x + y + z));
$ node generate-assertions.js
eq(curried(1, 2, 3, 4, 5), 15);
eq(curried(1, 2, 3, 4)(5), 15);
eq(curried(1, 2, 3)(4, 5), 15);
eq(curried(1, 2, 3)(4)(5), 15);
eq(curried(1, 2)(3, 4, 5), 15);
eq(curried(1, 2)(3, 4)(5), 15);
eq(curried(1, 2)(3)(4, 5), 15);
eq(curried(1, 2)(3)(4)(5), 15);
eq(curried(1)(2, 3, 4, 5), 15);
eq(curried(1)(2, 3, 4)(5), 15);
eq(curried(1)(2, 3)(4, 5), 15);
eq(curried(1)(2, 3)(4)(5), 15);
eq(curried(1)(2)(3, 4, 5), 15);
eq(curried(1)(2)(3, 4)(5), 15);
eq(curried(1)(2)(3)(4, 5), 15);
eq(curried(1)(2)(3)(4)(5), 15);
You could run this for each of the other 🍛 functions as well.
We should make it clear that the functions are curried Ramda-style. I'd like to see two applications of each function. For example: > toUrl('https:')(S.Nothing)('example.com')(S.Just('443'))('/foo/bar')
'https://example.com:443/foo/bar'
> toUrl('https:', S.Nothing, 'example.com', S.Just('443'), '/foo/bar')
'https://example.com:443/foo/bar' |
function curry5(f, v, w, x, y, z) { | ||
return f(v, w, x, y, z); | ||
} | ||
S.curry5 = def('curry5', {}, [$.Function, a, b, c, d, e, f], curry5); |
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'd like to use r
(result?) in place of f
, because in another pull request f
will become a unary type variable. In other words, its type will be Type -> Type
rather than Type
, and it will no longer be suitable in this context. Using a different type variable now will save me from having to change it in the other pull request.
Chippin' away. Thanks for that script. |
eq(curried(1, 2, 3), 6); | ||
eq(curried(1)(2)(3), 6); | ||
eq(curried(1, 2)(3), 6); | ||
eq(curried(1)(2, 3), 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.
For consistency, let's use the script to generate the assertions for curry2
and curry3
as well. You have all the combinations, but my obsessive streak wants to see them consistently ordered. 😜
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 also changed them to use + instead of * in the curried 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.
Works for me. 👍
Looking good, @laduke! After addressing the final comment could you squash the commits and rebase on |
eq(curried(1)(2)(3, 4)(5), 15); | ||
eq(curried(1)(2)(3)(4, 5), 15); | ||
eq(curried(1)(2)(3)(4)(5), 15); | ||
}); |
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.
Could we have an empty line after the last assertion? Sorry for the pedantry. No more requests, I promise!
Please use git commit --amend
when making the change. :)
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 deserve every word of it.
🌳 Terrific first contribution! Thanks for all your work on this. :) |
🎉 |
|
Hi, first pull request here. Thanks for the hand-holding. This closes #277.
Things not complete or I'm not sure about:
Looks like all of the examples in the readme are one liners.
var e = $.TypeVariable('e');
is skipped and I don't know why. So curry4 and 5 don't have an 'e':S.curry4 = def('curry4', {}, [$.Function, a, b, c, d, f], curry4);
I have
function(v, w, x, y, z)
...make
the README and commit, or does that happen later?