-
-
Notifications
You must be signed in to change notification settings - Fork 87
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
feat: concatAll #404
feat: concatAll #404
Conversation
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.
Thank you. Nice work! There are couple of issues we need to solve before merging.
src/index.d.ts
Outdated
* Returns the result of concatenating all semigroups (such as arrays or strings) in passed foldable (such as an array). | ||
* Returns null if empty foldable was passed. | ||
*/ | ||
concatAll<S extends Semigroup>(foldable: Foldable<S>): S | null; |
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.
@BjornMelgaard can you review this pls ?
src/concatAll.js
Outdated
* @sig Semigroup s => Foldable s f => f -> (s | null) | ||
* @param {Foldable<Semigroup>} foldable foldable with semigroups to concatenate | ||
* @return {Semigroup|null} concatenated semigroups, or null, if empty foldable was passed | ||
* @see {@link http://ramdajs.com/docs/#defaultTo|defaultTo} |
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 defaultTo ?
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.
Because it's a way to get rid of the returned null
.
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.
Yes but it's just an implementation detail. Consumer of the api should not be conserned with that. Actually I'm more inclined to use undefined
instead of null. I've used some ramda functions today and noticed the ramda is never returning null
. Always undefined.
http://ramdajs.com/docs and search for | undefined
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.
Agree with undefined
.
Well, actually the user of it should be aware of concerned that it'll return null or undefined when it receives empty foldable.
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.
Yes but link to defaultTo
using @see
doesn't do the job. Actually I think that there should only bee two @see
tags with reference to R.concat
and RA.concatRight
. We should also add @see
to concatRight
that referece to RA.concatAll
.
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 don't think it's necessary to reference RA.concatRight
.
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.
Also, I'm of two minds about whether or not @see
R.unnest
and R.join
, from one perspective, concatAll
does a similar thing, except it has no sensible return value for empty foldable. From the other, R.unnest
and concatAll
have significantly different requirements about their parameters (Chain
vs Foldable Semigroup
).
test/concatAll.js
Outdated
eq(concatAll(['1', '2', '3']), '123'); | ||
}); | ||
|
||
it('returns null if empty foldable was passed', 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.
Your tests are failing on some ramda version. Ramdas utilities become fantasy land compatible in some specific version. We have a pattern of future detection in tests.
See here
Line 50 in a3109fc
if (isFantasyLandSupported) { |
test/concatAll.js
Outdated
}); | ||
|
||
it('throws if non-foldable is passed', function() { | ||
assert.throws(() => concatAll(null), TypeError); |
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 don't see any tests with Semigroups.
Use RA.Identity
or monet to create couple of tests; see here
Line 52 in a3109fc
eq(RA.notBoth(Just(true), Just(true)), Just(false)); |
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 I'll test it on NonEmptyList
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.
Try I'm looking forward to see it
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.
Done
src/concatAll.js
Outdated
* @since {@link https://char0n.github.io/ramda-adjunct/2.6.0|v2.6.0} | ||
* @category List | ||
* @sig Semigroup s => Foldable s f => f -> (s | null) | ||
* @param {Foldable<Semigroup>} foldable foldable with semigroups to concatenate |
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.
Foldable<Semigroup>
is not true for all version of ramda we are supporting.
I'd go for the following just like R.concat do
@sig [a] -> [a] -> [a]
@sig String -> String -> String
And add a sentence: Can also concatenate multiple members of a fantasy-land compatible semigroup.
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.
Partly done, added the signatures, but didn't remove the previous one.
src/concatAll.js
Outdated
const nullSemigroup = { [fl.concat]: identity }; | ||
|
||
/** | ||
* Returns the result of concatenating all semigroups (such as arrays or strings) in passed foldable (such as an array). |
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.
Returns the result of concatenating the given lists or strings.
Note: R.concat expects all items to be of the same type. It will throw an error if you concat an Array with a non-Array value.
Dispatches to the concat method of the item, if present. Can also concatenate multiple members of a fantasy-land compatible semigroup.
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 should also add info about returning undefined. It's missing in this description. Please do so.
test/concatAll.js
Outdated
import eq from './shared/eq'; | ||
|
||
describe('concatAll', function() { | ||
it('concatenates arrays', 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.
Prefer should notations; the same applies for other tests
it('should concatenate arrays'
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.
Done.
src/concatAll.js
Outdated
import stubNull from './stubNull'; | ||
import fl from './fantasy-land/mapping'; | ||
|
||
const nullSemigroup = { [fl.concat]: identity }; |
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 guess we'll need to change this to be compatible from ramda 0.19.1 to ramda 0.25.0
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.
Already done. Changed back to 'concat'
.
src/concatAll.js
Outdated
* @sig Semigroup s => Foldable s f => f -> (s | undefined) | ||
* @param {Foldable<Semigroup>} foldable foldable with semigroups to concatenate | ||
* @return {Semigroup|null} concatenated semigroups, or undefined, if empty foldable was passed | ||
* @see {@link http://ramdajs.com/docs/#defaultTo|defaultTo} |
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 drop defaultTo and add RA.concatRight
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.
Remove or leave those in?
/*
* @see {@link http://ramdajs.com/docs/#unnest|unnest}
* @see {@link http://ramdajs.com/docs/#join|join}
*/
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.
You explained these two in prev comments and I guess it make sense to keep them.
src/concatAll.js
Outdated
|
||
import stubUndefined from './stubUndefined'; | ||
|
||
const nullSemigroup = { concat: identity }; |
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.
Null semigroup may be incorrect name for this. Shouldn't we go for something like leftIdentitySemigroup
?
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.
Done (but not yet pushed, but it's still useful to mark it as done for me)
src/concatAll.js
Outdated
const nullSemigroup = { concat: identity }; | ||
|
||
/** | ||
* Returns the result of concatenating all semigroups (such as arrays or strings) in passed foldable (such as an array). |
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.
You're being too academic on this. This is not the way how Ramda documents it's api. So again I propose the following:
Returns the result of concatenating the given lists or strings.
Note: RA.concatAll expects all elements to be of the same type. It will throw an error if you concat an Array with a non-Array value.
Dispatches to the concat method of the preceding element, if present. Can also concatenate multiple elements of a [fantasy-land compatible semigroup](https://github.com/fantasyland/fantasy-land#semigroup).
Returns undefined if empty array was passed.
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.
Right.
Returns undefined if empty array was passed.
Should I mention R.defaultTo
there somehow? "pipe the result through R.defaultTo
to replace the undefined with something useful"
The best wording I came up with.
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.
Nope we should not do that. For me it's the same as using R.find
function with signature (a → Boolean) → [a] → a | undefined
. They don't tell us there what to do with undefined.
Some functions just returns undefined, as an expected output. I trying to understand your reasoning but I don't see it, I am sorry. Should we also mention defaultTo
when documenting R.prop
function or R.nth
? I think not.
src/concatAll.js
Outdated
* @memberOf RA | ||
* @since {@link https://char0n.github.io/ramda-adjunct/2.6.0|v2.6.0} | ||
* @category List | ||
* @sig [[a]] -> ([a] | undefined) |
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.
Drop the redundant parens and use Undefined
to denote a Category not a value
[[a]] -> [a] | Undefined
src/concatAll.js
Outdated
* @since {@link https://char0n.github.io/ramda-adjunct/2.6.0|v2.6.0} | ||
* @category List | ||
* @sig [[a]] -> ([a] | undefined) | ||
* @sig [String] -> (String | undefined) |
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.
Drop the redundant parens and use Undefined
to denote a Category not a value
[String] -> String | Undefined
src/concatAll.js
Outdated
* @sig [String] -> (String | undefined) | ||
* @sig Semigroup s => Foldable s f => f -> (s | undefined) | ||
* @param {Foldable<Semigroup>} foldable foldable with semigroups to concatenate | ||
* @return {Semigroup|null} concatenated semigroups, or undefined, if empty foldable was passed |
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.
@return {Array|string|undefined} Concatenated elements
test/concatAll.js
Outdated
assert.throws(() => concatAll([1, 2, null, true]), TypeError); | ||
}); | ||
|
||
it('should throw if foldable contains non-compatible semigroups', 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.
This test is not passing on ramda 0.23.0
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.
Should I remove it then?
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 have to find out why it's not passing and do feature detection to enable/disable test depending on features R provides for us in particular version
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.
Ramda 0.23 just doesn't throw for concating string and array, so I changed the test to try to concat array and string ;)
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.
Done.
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 fails in 0.21 tho!
I think I'll just remove the test.
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.
Ramda should be testing that in R.concat
anyway.
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.
Just comment the test out, don't remove it. I'll play with that after merge.
test/concatAll.js
Outdated
assert.throws(() => concatAll(null), TypeError); | ||
}); | ||
|
||
it('should throw if foldable contains non-semigroups', 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.
Your test description contains branching logic. We use more proper mechanism for this.
context('when foldable contains non-semigroups', function () {
specify('should throw error', function () {
assert.throws(() => concatAll([1, 2, null, true]), TypeError);
});
});
Ref:
Line 41 in a3109fc
context('when the first function returns false', 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.
Done. It looks so neat now. Thanks, I have no experience in testing.
src/index.d.ts
Outdated
* Returns the result of concatenating all semigroups (such as arrays or strings) in passed foldable (such as an array). | ||
* Returns null if empty foldable was passed. | ||
*/ | ||
concatAll<S extends Semigroup>(foldable: Foldable<S>): S | null; |
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.
concatAll<S extends Semigroup>(foldable: Foldable<S>): S | undefined;
@@ -376,6 +385,12 @@ declare namespace RamdaAdjunct { | |||
*/ | |||
ensureArray<T>(value: T | T[]): T[]; | |||
|
|||
/** |
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.
Don't forget to align this description with the one I proposed in previous comment
test/concatAll.js
Outdated
import { assert } from 'chai'; | ||
import { NEL, Nil } from 'monet'; | ||
|
||
import { concatAll } from '../src'; |
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.
Use following notation in tests pls.
import * as RA from '../src';
Ref:
ramda-adjunct/test/isBoolean.js
Line 4 in 2f5173a
import eq from './shared/eq'; |
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.
Will do. Why tho?
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's a convention we use through out our tests to distinguish between R and RA functions.
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.
Done.
Oh ffs, I thought CI would pass it by now |
Finally. If everything's fine, merge-squash it or something, don't rebase all of the commits on master, that'd be messy. If you don't want to merge-squash, I can rebase-squash and force-push. |
@GingerPlusPlus : that's fine, here is "squash and merge" for each PRs. |
@guillaumearm The thing is, I don't know who does it show as the creator of the merged commit |
@GingerPlusPlus : don't worry about that. |
Resolves #109.