Skip to content

Commit

Permalink
version 2.6.4
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti committed Jun 9, 2020
1 parent 4471dcb commit 0c2b9a1
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 24 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
**Note**: Gaps between patch versions are faulty/broken releases. **Note**: A feature tagged as Experimental is in a
high state of flux, you're at risk of it changing without notice.

# 2.6.4

- **Bug Fix**
- `ReadonlyMap`
- `traverseWithIndex` should sort the keys (@gcanti)
- `ReadonlyRecord`
- `traverseWithIndex` should sort the keys (@gcanti)

# 2.6.3

- **Polish**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fp-ts",
"version": "2.6.3",
"version": "2.6.4",
"description": "Functional programming in TypeScript",
"files": [
"lib",
Expand Down
22 changes: 11 additions & 11 deletions src/ReadonlyMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,14 +720,14 @@ export function getWitherable<K>(O: Ord<K>): Witherable2C<URI, K> & TraversableW

const traverseWithIndex = <F>(
F: Applicative<F>
): (<K, A, B>(ta: ReadonlyMap<K, A>, f: (k: K, a: A) => HKT<F, B>) => HKT<F, ReadonlyMap<K, B>>) => {
return <K, A, B>(ta: ReadonlyMap<K, A>, f: (k: K, a: A) => HKT<F, B>) => {
): (<A, B>(ta: ReadonlyMap<K, A>, f: (k: K, a: A) => HKT<F, B>) => HKT<F, ReadonlyMap<K, B>>) => {
return <A, B>(ta: ReadonlyMap<K, A>, f: (k: K, a: A) => HKT<F, B>) => {
let fm: HKT<F, ReadonlyMap<K, B>> = F.of(empty)
const entries = ta.entries()
let e: Next<readonly [K, A]>
// tslint:disable-next-line: strict-boolean-expressions
while (!(e = entries.next()).done) {
const [key, a] = e.value
const ks = keysO(ta)
const len = ks.length
for (let i = 0; i < len; i++) {
const key = ks[i]
const a = ta.get(key)!
fm = F.ap(
F.map(fm, (m) => (b: B) => new Map(m).set(key, b)),
f(key, a)
Expand All @@ -739,12 +739,12 @@ export function getWitherable<K>(O: Ord<K>): Witherable2C<URI, K> & TraversableW

const traverse = <F>(
F: Applicative<F>
): (<K, A, B>(ta: ReadonlyMap<K, A>, f: (a: A) => HKT<F, B>) => HKT<F, ReadonlyMap<K, B>>) => {
): (<A, B>(ta: ReadonlyMap<K, A>, f: (a: A) => HKT<F, B>) => HKT<F, ReadonlyMap<K, B>>) => {
const traverseWithIndexF = traverseWithIndex(F)
return (ta, f) => traverseWithIndexF(ta, (_, a) => f(a))
}

const sequence = <F>(F: Applicative<F>): (<K, A>(ta: ReadonlyMap<K, HKT<F, A>>) => HKT<F, ReadonlyMap<K, A>>) => {
const sequence = <F>(F: Applicative<F>): (<A>(ta: ReadonlyMap<K, HKT<F, A>>) => HKT<F, ReadonlyMap<K, A>>) => {
const traverseWithIndexF = traverseWithIndex(F)
return (ta) => traverseWithIndexF(ta, (_, a) => a)
}
Expand Down Expand Up @@ -774,7 +774,7 @@ export function getWitherable<K>(O: Ord<K>): Witherable2C<URI, K> & TraversableW
traverseWithIndex,
wilt: <F>(
F: Applicative<F>
): (<K, A, B, C>(
): (<A, B, C>(
wa: ReadonlyMap<K, A>,
f: (a: A) => HKT<F, Either<B, C>>
) => HKT<F, Separated<ReadonlyMap<K, B>, ReadonlyMap<K, C>>>) => {
Expand All @@ -783,7 +783,7 @@ export function getWitherable<K>(O: Ord<K>): Witherable2C<URI, K> & TraversableW
},
wither: <F>(
F: Applicative<F>
): (<K, A, B>(wa: ReadonlyMap<K, A>, f: (a: A) => HKT<F, Option<B>>) => HKT<F, ReadonlyMap<K, B>>) => {
): (<A, B>(wa: ReadonlyMap<K, A>, f: (a: A) => HKT<F, Option<B>>) => HKT<F, ReadonlyMap<K, B>>) => {
const traverseF = traverse(F)
return (wa, f) => F.map(traverseF(wa, f), compact)
}
Expand Down
24 changes: 12 additions & 12 deletions src/ReadonlyRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -765,10 +765,10 @@ const reduceWithIndex_: <A, B>(fa: Readonly<Record<string, A>>, b: B, f: (i: str
f
) => {
let out = b
const keys = Object.keys(fa).sort()
const len = keys.length
const ks = keys(fa)
const len = ks.length
for (let i = 0; i < len; i++) {
const k = keys[i]
const k = ks[i]
out = f(k, out, fa[k])
}
return out
Expand All @@ -778,10 +778,10 @@ const foldMapWithIndex_: <M>(M: Monoid<M>) => <A>(fa: Readonly<Record<string, A>
M
) => (fa, f) => {
let out = M.empty
const keys = Object.keys(fa).sort()
const len = keys.length
const ks = keys(fa)
const len = ks.length
for (let i = 0; i < len; i++) {
const k = keys[i]
const k = ks[i]
out = M.concat(out, f(k, fa[k]))
}
return out
Expand All @@ -793,10 +793,10 @@ const reduceRightWithIndex_: <A, B>(fa: Readonly<Record<string, A>>, b: B, f: (i
f
) => {
let out = b
const keys = Object.keys(fa).sort()
const len = keys.length
const ks = keys(fa)
const len = ks.length
for (let i = len - 1; i >= 0; i--) {
const k = keys[i]
const k = ks[i]
out = f(k, fa[k], out)
}
return out
Expand Down Expand Up @@ -879,12 +879,12 @@ const traverseWithIndex_ = <F>(F: Applicative<F>) => <A, B>(
ta: ReadonlyRecord<string, A>,
f: (k: string, a: A) => HKT<F, B>
) => {
const keys = Object.keys(ta)
if (keys.length === 0) {
const ks = keys(ta)
if (ks.length === 0) {
return F.of(empty)
}
let fr: HKT<F, Record<string, B>> = F.of({})
for (const key of keys) {
for (const key of ks) {
fr = F.ap(
F.map(fr, (r) => (b: B) => {
r[key] = b
Expand Down
19 changes: 19 additions & 0 deletions test/ReadonlyMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Either, left, right } from '../src/Either'
import { Eq, eqNumber, fromEquals } from '../src/Eq'
import { identity, pipe, Refinement } from '../src/function'
import * as I from '../src/Identity'
import * as IO from '../src/IO'
import { monoidString } from '../src/Monoid'
import { none, option, Option, some } from '../src/Option'
import { fromCompare, ord, ordNumber, ordString } from '../src/Ord'
Expand Down Expand Up @@ -742,6 +743,24 @@ describe('ReadonlyMap', () => {
describe('getWitherable', () => {
const W = _.getWitherable(ordUser)

it('traverseWithIndex should sort the keys', () => {
const W = _.getWitherable(ordString)
// tslint:disable-next-line: readonly-array
const log: Array<string> = []
const append = (message: string): IO.IO<void> => () => {
log.push(message)
}

W.traverseWithIndex(IO.io)(
new Map([
['b', append('b')],
['a', append('a')]
]),
(_, io) => io
)()
assert.deepStrictEqual(log, ['a', 'b'])
})

it('mapWithIndex', () => {
const mapWithIndex = W.mapWithIndex
const aa1 = new Map<User, number>([[{ id: 'aa' }, 1]])
Expand Down
15 changes: 15 additions & 0 deletions test/ReadonlyRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { left, right } from '../src/Either'
import { eqNumber } from '../src/Eq'
import { identity, pipe } from '../src/function'
import * as I from '../src/Identity'
import * as IO from '../src/IO'
import { monoidString } from '../src/Monoid'
import { getOrElse, isSome, none, option, Option, some } from '../src/Option'
import { readonlyArray, zip } from '../src/ReadonlyArray'
Expand Down Expand Up @@ -272,6 +273,20 @@ describe('ReadonlyRecord', () => {
assert.deepStrictEqual(_.toUnfoldable(readonlyArray)({ a: 1 }), [['a', 1]])
})

it('traverseWithIndex should sort the keys', () => {
// tslint:disable-next-line: readonly-array
const log: Array<string> = []
const append = (message: string): IO.IO<void> => () => {
log.push(message)
}

pipe(
{ b: append('b'), a: append('a') },
_.traverseWithIndex(IO.io)((_, io) => io)
)()
assert.deepStrictEqual(log, ['a', 'b'])
})

it('traverseWithIndex', () => {
const d1 = { k1: 1, k2: 2 }
const t1 = _.traverseWithIndex(option)((k, n: number): Option<number> => (k !== 'k1' ? some(n) : none))(d1)
Expand Down

0 comments on commit 0c2b9a1

Please sign in to comment.