-
-
Notifications
You must be signed in to change notification settings - Fork 88
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
Changes from 5 commits
dd14b4d
f2e3e45
c988c99
6d076d4
366f7dc
bd8156c
850a28b
1b52f5c
9eec5b9
1dfc84f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { concat, identical, identity, pipe, when, reduce } from 'ramda'; | ||
|
||
import stubUndefined from './stubUndefined'; | ||
|
||
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 commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right.
Should I mention The best wording I came up with. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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 |
||
* Returns undefined if empty foldable was passed. | ||
* | ||
* @func concatAll | ||
* @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 commentThe reason will be displayed to describe this comment to others. Learn more. Drop the redundant parens and use [[a]] -> [a] | Undefined |
||
* @sig [String] -> (String | undefined) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drop the redundant parens and use [String] -> String | Undefined |
||
* @sig Semigroup s => Foldable s f => f -> (s | undefined) | ||
* @param {Foldable<Semigroup>} foldable foldable with semigroups to concatenate | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@sig [a] -> [a] -> [a]
@sig String -> String -> String And add a sentence: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Partly done, added the signatures, but didn't remove the previous one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @param {Array.<Array|string>} list List containing elements that will be concatenated |
||
* @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 commentThe reason will be displayed to describe this comment to others. Learn more. @return {Array|string|undefined} Concatenated elements |
||
* @see {@link http://ramdajs.com/docs/#defaultTo|defaultTo} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Because it's a way to get rid of the returned There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 http://ramdajs.com/docs and search for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree with 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 commentThe reason will be displayed to describe this comment to others. Learn more. Yes but link to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it's necessary to reference There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I'm of two minds about whether or not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please drop defaultTo and add There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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. |
||
* @see {@link http://ramdajs.com/docs/#concat|concat} | ||
* @see {@link http://ramdajs.com/docs/#unnest|unnest} | ||
* @see {@link http://ramdajs.com/docs/#join|join} | ||
* @example | ||
* | ||
* concatAll([[1], [2], [3]]); //=> [1, 2, 3] | ||
* concatAll(['1', '2', '3']); //=> '123' | ||
* concatAll([]); //=> undefined; | ||
*/ | ||
const concatAll = pipe( | ||
reduce(concat, nullSemigroup), | ||
when(identical(nullSemigroup), stubUndefined) | ||
); | ||
|
||
export default concatAll; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,15 @@ declare namespace RamdaAdjunct { | |
ap<U>(fn: Apply<(t: T) => U>): Apply<U>; | ||
} | ||
|
||
interface Foldable<T> { | ||
reduce<Acc>(fn: (acc: Acc, val: T) => Acc, initAcc: Acc): Acc; | ||
} | ||
|
||
interface Semigroup { | ||
// https://www.typescriptlang.org/docs/handbook/advanced-types.html#polymorphic-this-types | ||
concat(other: this): this; | ||
} | ||
|
||
interface Catamorphism<T> { | ||
cata<T1>(leftFn: (v: T1) => T, rightFn: (v: T1) => T): T; | ||
} | ||
|
@@ -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 commentThe 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 |
||
* 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 commentThe reason will be displayed to describe this comment to others. Learn more. @BjornMelgaard can you review this pls ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. concatAll<S extends Semigroup>(foldable: Foldable<S>): S | undefined; |
||
|
||
/** | ||
* Returns the result of concatenating the given lists or strings. | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,35 @@ | ||||
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 commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||
import eq from './shared/eq'; | ||||
|
||||
describe('concatAll', function() { | ||||
it('should concatenate arrays', function() { | ||||
eq(concatAll([[1], [2], [3]]), [1, 2, 3]); | ||||
}); | ||||
|
||||
it('should concatenate strings', function() { | ||||
eq(concatAll(['1', '2', '3']), '123'); | ||||
}); | ||||
|
||||
it('should concatenate semigroups', function() { | ||||
eq(concatAll([NEL(1), NEL(2)]), NEL(1, NEL(2, Nil))); | ||||
}); | ||||
|
||||
it('should returns undefined if empty foldable was passed', function() { | ||||
eq(concatAll([]), undefined); | ||||
}); | ||||
|
||||
it('should throw if non-foldable is passed', function() { | ||||
assert.throws(() => concatAll(null), TypeError); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see any tests with Semigroups. Use Line 52 in a3109fc
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I'll test it on There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||
}); | ||||
|
||||
it('should throw if foldable contains non-semigroups', function() { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||||
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 commentThe 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 commentThe 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 commentThe 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 commentThe 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 commentThe 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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Ramda should be testing that in There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||||
assert.throws(() => concatAll(['1', [1]]), 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.
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)