// ets_tracing: off import * as R from "@effect-ts/system/Collections/Immutable/Dictionary" import * as Tp from "@effect-ts/system/Collections/Immutable/Tuple" import * as O from "@effect-ts/system/Option" import type { MutableRecord } from "@effect-ts/system/Support/Mutable" import type { Associative } from "../../../Associative/index.js" import type { Closure } from "../../../Closure/index.js" import * as E from "../../../Either/index.js" import type { Equal } from "../../../Equal/index.js" import { makeEqual } from "../../../Equal/index.js" import { identity, pipe, tuple } from "../../../Function/index.js" import type { Identity } from "../../../Identity/index.js" import { makeIdentity } from "../../../Identity/index.js" import type { DictionaryURI } from "../../../Modules/index.js" import type * as HKT from "../../../Prelude/HKT/index.js" import type { Foldable, URI } from "../../../Prelude/index.js" import * as P from "../../../Prelude/index.js" import { succeedF } from "../../../Prelude/index.js" import type { Show } from "../../../Show/index.js" import * as A from "../Array/index.js" export * from "@effect-ts/system/Collections/Immutable/Dictionary" /** * Traverse Record with Applicative, passing index to f */ export const forEachWithIndexF = P.implementForEachWithIndexF<[URI]>()( (_) => (G) => { const succeed = succeedF(G) return (f) => (fa) => { let base = succeed>({} as any) for (const k of Object.keys(fa)) { base = G.map( ({ tuple: [x, b] }: Tp.Tuple<[R.Dictionary, typeof _.B]>) => Object.assign(x, { [k]: b }) )(G.both(f(k, fa[k]!))(base)) } return base } } ) /** * Traverse Record with Applicative */ export const forEachF = P.implementForEachF<[URI]>()( (_) => (G) => (f) => forEachWithIndexF(G)((_, a) => f(a)) ) /** * Fold + MapWithIndex */ export const foldMapWithIndex: P.FoldMapWithIndexFn<[URI]> = (I) => (f) => R.reduceWithIndex(I.identity, (k, b, a) => I.combine(b, f(k, a))) /** * Fold + Map */ export const foldMap: P.FoldMapFn<[URI]> = (I) => (f) => foldMapWithIndex(I)((_, a) => f(a)) /** * WiltWithIndex's separate */ export const separateWithIndexF = P.implementSeparateWithIndexF<[URI]>()( () => (G) => (f) => (x) => pipe( x, R.collect(tuple), A.separateF(G)(([k, a]) => pipe( f(k, a), G.map( E.bimap( (b) => Tp.tuple(k, b), (a) => Tp.tuple(k, a) ) ) ) ), G.map(({ tuple: [left, right] }) => Tp.tuple(R.fromArray(left), R.fromArray(right)) ) ) ) /** * Wilt's separate */ export const separateF = P.implementSeparateF<[URI]>()( () => (G) => (f) => separateWithIndexF(G)((_, a) => f(a)) ) /** * WitherWithIndex's compactWithIndex */ export const compactWithIndexF = P.implementCompactWithIndexF<[URI]>()( () => (G) => (f) => (x) => pipe( x, R.collect(tuple), A.compactF(G)(([k, a]) => pipe(f(k, a), G.map(O.map((b) => Tp.tuple(k, b))))), G.map(R.fromArray) ) ) /** * Wither's compact */ export const compactF = P.implementCompactF<[URI]>()( () => (G) => (f) => compactWithIndexF(G)((_, a) => f(a)) ) /** * Like fromFoldable + map */ export function fromFoldableMap_( M: Closure, F: Foldable ): ( fa: HKT.Kind, f: (a: A) => Tp.Tuple<[string, B]> ) => R.Dictionary export function fromFoldableMap_( M: Closure, F: Foldable> ): (fa: HKT.HKT, f: (a: A) => Tp.Tuple<[string, B]>) => R.Dictionary { return (fa: HKT.HKT, f: (a: A) => Tp.Tuple<[string, B]>) => { return F.reduce>({}, (r, a) => { const [k, b] = f(a).tuple r[k] = Object.prototype.hasOwnProperty.call(r, k) ? M.combine(r[k]!, b) : b return r })(fa) } } /** * Like fromFoldable + map */ export function fromFoldableMap( M: Closure, F: Foldable ): ( f: (a: A) => Tp.Tuple<[string, B]> ) => ( fa: HKT.Kind ) => R.Dictionary export function fromFoldableMap( M: Closure, F: Foldable> ): (f: (a: A) => Tp.Tuple<[string, B]>) => (fa: HKT.HKT) => R.Dictionary { const ff = fromFoldableMap_(M, F) return (f: (a: A) => Tp.Tuple<[string, B]>) => (fa: HKT.HKT) => ff(fa, f) } /** * Construct a Record from a Foldable and a Closure of values */ export function fromFoldable( M: Closure, F: Foldable ): ( fa: HKT.Kind> ) => R.Dictionary export function fromFoldable( M: Closure, F: Foldable> ): (fa: HKT.HKT>) => R.Dictionary { const fromFoldableMapM = fromFoldableMap(M, F) return fromFoldableMapM(identity) } /** * Get Show of Record given Show of values */ export function getShow(S: Show): Show> { return { show: (r) => { const elements = R.collect((k, a: A) => `${JSON.stringify(k)}: ${S.show(a)}`)( r ).join(", ") return elements === "" ? "{}" : `{ ${elements} }` } } } /** * Test whether one record contains all of the keys and values contained in another record */ export function isSubrecord_( E: Equal ): (x: R.Dictionary, y: R.Dictionary) => boolean { return (x, y) => { for (const k in x) { if (!Object.prototype.hasOwnProperty.call(y, k) || !E.equals(x[k]!, y[k]!)) { return false } } return true } } /** * Test whether one record contains all of the keys and values contained in another record */ export function isSubrecord( E: Equal ): (y: R.Dictionary) => (x: R.Dictionary) => boolean { const is = isSubrecord_(E) return (y) => (x) => is(x, y) } /** * Get Equals for record given Equals of values */ export function getEqual(E: Equal): Equal> { const isSubrecordE = isSubrecord_(E) return makeEqual((x, y) => isSubrecordE(x, y) && isSubrecordE(y, x)) } /** * Returns a `Identity` instance for records given a `Associative` instance for their values */ export function getIdentity(S: Associative): Identity> { return makeIdentity(R.empty as R.Dictionary, (x, y) => { if (x === R.empty) { return y } if (y === R.empty) { return x } const keys = Object.keys(y) const len = keys.length if (len === 0) { return x } const r: MutableRecord = { ...x } for (let i = 0; i < len; i++) { const k = keys[i]! r[k] = Object.prototype.hasOwnProperty.call(x, k) ? S.combine(x[k]!, y[k]!) : y[k]! } return r }) }