Skip to main content
Module

x/fun/set.ts

A collection of algebraic data types, lenses, and schemables based on a light weight higher kinded type implementation. Written for deno.
Latest
File
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
/** * ReadonlySet is a readonly product structure over objects * and it operates on object equality for deduplication. * * @module ReadonlySet * @since 2.0.0 */
import type { $, Kind, Out } from "./kind.ts";import type { Applicable } from "./applicable.ts";import type { Combinable } from "./combinable.ts";import type { Comparable } from "./comparable.ts";import type { Either } from "./either.ts";import type { Filterable } from "./filterable.ts";import type { Flatmappable } from "./flatmappable.ts";import type { Foldable } from "./foldable.ts";import type { Initializable } from "./initializable.ts";import type { Mappable } from "./mappable.ts";import type { Option } from "./option.ts";import type { Pair } from "./pair.ts";import type { Predicate } from "./predicate.ts";import type { Refinement } from "./refinement.ts";import type { Showable } from "./showable.ts";import type { Traversable } from "./traversable.ts";import type { Wrappable } from "./wrappable.ts";
import { flow, identity, pipe } from "./fn.ts";import { fromCompare } from "./comparable.ts";import { fromCombine } from "./combinable.ts";import { createBind, createTap } from "./flatmappable.ts";import { createBindTo } from "./mappable.ts";import * as O from "./option.ts";import * as E from "./either.ts";
/** * Extract the inner type of a ReadonlySet * * @since 2.0.0 */export type TypeOf<T> = T extends ReadonlySet<infer A> ? A : never;
/** * Specifies ReadonlySet as a Higher Kinded Type, with covariant * parameter A corresponding to the 0th index of any substitutions. * * @since 2.0.0 */export interface KindReadonlySet extends Kind { readonly kind: ReadonlySet<Out<this, 0>>;}
/** * Constructs a new ReadonlySet over type A that conuains no values. * * @example * ```ts * import * as S from "./set.ts"; * * const result = S.init<number>(); // ReadonlySet<number> with no members. * ``` * * @since 2.0.0 */export function init<A = never>(): ReadonlySet<A> { return new Set();}
/** * Constructs a new ReadonlySet<A> from an arbitrary number * of values. * * @example * ```ts * import * as S from "./set.ts"; * * const result = S.set(1, 2, 3); // ReadonlySet<number> * ``` * * @since 2.0.0 */export function set<A>(...as: readonly [A, ...A[]]): ReadonlySet<A> { return new Set(as);}
/** * Copies an existing ReadonlySet into a new ReadonlySet, keeping * references to the original members. * * @example * ```ts * import * as S from "./set.ts"; * * const original = S.set(1, 2, 3); * const copy = S.copy(original); * * const result1 = original === copy; // false * * const has = (value: number) => original.has(value) === copy.has(value); * * const result2 = has(1); // true; * const result3 = has(10); // true; * ``` * * @since 2.0.0 */export function copy<A>(ua: ReadonlySet<A>): ReadonlySet<A> { return new Set(ua);}
/** * Operates like Array.some, testing values in a ReadonlySet with a Predicate * until either the predicate returns true for a value or all of the * values have been tested. Shortcircuits on the first value that * returns true. This is the dual of every. * * @example * ```ts * import * as S from "./set.ts"; * * const some = S.some((n: number) => n > 0); * * const result1 = some(S.set(1, 2, 3)); // true * const result2 = some(S.set(0)); // false * const result3 = some(S.init()); // false * const result4 = some(S.set(-1, -2, -3, 1)); // true * ``` * * @since 2.0.0 */export function some<A>( predicate: Predicate<A>,): (ua: ReadonlySet<A>) => boolean { return (ua) => { for (const a of ua) { if (predicate(a)) { return true; } } return false; };}
/** * Operates like Array.every, testing values in a ReadonlySet with a Predicate * until either the predicate returns false for a value or all of the * values have been tested as true. Shortcircuits on the first value that * returns false. This is the dual of some. * * @example * ```ts * import * as S from "./set.ts"; * * const some = S.some((n: number) => n > 0); * * const result1 = some(S.set(1, 2, 3)); // true * const result2 = some(S.set(0)); // false * const result3 = some(S.init()); // false * const result4 = some(S.set(-1, -2, -3, 1)); // true * ``` * * @since 2.0.0 */export function every<A>( predicate: Predicate<A>,): (ua: ReadonlySet<A>) => boolean { return (ua) => { for (const a of ua) { if (!predicate(a)) { return false; } } return true; };}
/** * Given an insuance of Comparable<A> create a function * that takes a value A and returns a predicate over * ReadonlySet<A> the returns true if there are any * members of the set that are equal to the value. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import { pipe } from "./fn.ts"; * * const elem = S.elem(N.ComparableNumber); * * const set = S.set(1, 2, 3); * * const result1 = pipe(set, elem(1)); // true * const result2 = pipe(set, elem(10)); // false * ``` * * @since 2.0.0 */export function elem<A>( { compare }: Comparable<A>,): (value: A) => (ua: ReadonlySet<A>) => boolean { return (a) => some(compare(a));}
/** * Given an instance of Comparable<A> create a function * that uakes a ReadonlySet<A> and returns a predicate over * a value A the returns true if the value is a member * of the set. This is like elem but with the set and value * parameters swapped. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * * const elemOf = S.elemOf(N.ComparableNumber); * * const set = S.set(1, 2, 3); * const inSet = elemOf(set); * * const result1 = inSet(1); // true * const result2 = inSet(10); // false * ``` * * @since 2.0.0 */export function elemOf<A>( S: Comparable<A>,): (ua: ReadonlySet<A>) => (a: A) => boolean { const _elem = elem(S); return (ua) => (a) => _elem(a)(ua);}
/** * Given an instance of Comparable<A> return a function * `second => first => boolean` that returns true when * every member of first is in second. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import { pipe } from "./fn.ts"; * * const subset = S.isSubset(N.ComparableNumber); * * const big = S.set(1, 2, 3, 4, 5); * const small = S.set(2, 4); * * const result1 = pipe(big, subset(small)); // false * const result2 = pipe(small, subset(big)); // true; * ``` * * @since 2.0.0 */export function isSubset<A>( S: Comparable<A>,): (second: ReadonlySet<A>) => (first: ReadonlySet<A>) => boolean { return flow(elemOf(S), every);}
/** * Given an instance of Comparable<A> return a function that takes * two ReadonlySet<A>s and merges them into a new ReadonlySet<A> * that contains all the elements from both sets. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import { pipe } from "./fn.ts"; * * const union = S.union(N.ComparableNumber); * const s1 = S.set(1, 2, 3, 4); * const s2 = S.set(3, 4, 5, 6); * * const result = pipe(s1, union(s2)); * // Set(1, 2, 3, 4, 5, 6) * ``` * * @since 2.0.0 */export function union<A>( S: Comparable<A>,): (second: ReadonlySet<A>) => (first: ReadonlySet<A>) => ReadonlySet<A> { return (second) => (first) => { const out = copy(first) as Set<A>; const isIn = elemOf(S)(out); for (const b of second) { if (!isIn(b)) { out.add(b); } } return out; };}
/** * Given an instance of Comparable<A> return a function that takes * two ReadonlySet<A>s and returns a new set with only * the elements that exist in both sets. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import { pipe } from "./fn.ts"; * * const intersect = S.intersection(N.ComparableNumber); * const s1 = S.set(1, 2, 3, 4); * const s2 = S.set(3, 4, 5, 6); * * const result = pipe(s1, intersect(s2)); * // Set(3, 4) * ``` * * @since 2.0.0 */export function intersection<A>( S: Comparable<A>,): (ua: ReadonlySet<A>) => (tb: ReadonlySet<A>) => ReadonlySet<A> { return (ua) => { const isIn = elemOf(S)(ua); return (tb) => { const out = new Set<A>(); for (const b of tb) { if (isIn(b)) { out.add(b); } } return out; }; };}
/** * Given an instance of Comparable<A> create a function that will * take a ReadonlySet<A> and return a new ReadonlySet<A> where * any members that are equal are deduplicated. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import * as E from "./comparable.ts"; * * const eq = E.struct({ num: N.ComparableNumber }); * const compact = S.compact(eq); * * const set = S.set({ num: 1 }, { num: 1 }, { num: 2 }); * // Set({ num: 1 }, { num: 1 }, { num: 2 }) * * const result = compact(set); // Set({ num: 1 }, { num: 2 }) * ``` * * @since 2.0.0 */export function compact<A>( S: Comparable<A>,): (ua: ReadonlySet<A>) => ReadonlySet<A> { return (ua) => { const out = new Set<A>(); const isIn = elemOf(S)(out); for (const a of ua) { if (!isIn(a)) { out.add(a); } } return out; };}
/** * Given a value A create a new ReadonlySet<A> that * contains that value. * * @example * ```ts * import * as S from "./set.ts"; * * const result = S.wrap(1); // Set(1); * ``` * * @since 2.0.0 */export function wrap<A>(a: A): ReadonlySet<A> { return set(a);}
/** * Given a function A -> I and a ReadonlySet<A> return * a new ReadonlySet<I> where the values were created * by passing each A through the A -> I function. * * @example * ```ts * import * as S from "./set.ts"; * import { pipe } from "./fn.ts"; * * const set = S.set("hello", "world", "goodbye"); * * const result = pipe( * set, * S.map(s => s.length), * ); // Set(5, 7); * ``` * * @since 2.0.0 */export function map<A, I>( fai: (a: A) => I,): (ua: ReadonlySet<A>) => ReadonlySet<I> { return (ua) => { const ti = new Set<I>(); for (const a of ua) { ti.add(fai(a)); } return ti; };}
/** * Given a ReadonlySet of functions A -> I and * a ReadonlySet<A> return a ReadonlySet<I> by applying * every function to every value A. * * @example * ```ts * import * as S from "./set.ts"; * import { pipe } from "./fn.ts"; * * type Person = { name: string, age: number }; * * const person = (name: string) => (age: number): Person => ({ name, age }); * * const result = pipe( * S.wrap(person), * S.apply(S.wrap("Brandon")), * S.apply(S.wrap(37)), * ); // ReadonlySet<Person> * ``` * * @since 2.0.0 */export function apply<A>( ua: ReadonlySet<A>,): <I>(ufai: ReadonlySet<(a: A) => I>) => ReadonlySet<I> { return <I>(ufai: ReadonlySet<(a: A) => I>): ReadonlySet<I> => { const ti = new Set<I>(); for (const a of ua) { for (const fai of ufai) { ti.add(fai(a)); } } return ti; };}
/** * Given a function A -> ReadonlySet<I> and a ReadonlySet<A> * return a ReadonlySet<I> created by applying the function * to every value A and joining all the resulting ReadonlySet<I>s. * * @example * ```ts * import * as S from "./set.ts"; * import { pipe } from "./fn.ts"; * * const set = S.set(1, 2, 3, 4, 5); * * const result = pipe( * set, * S.flatmap(n => S.set(n, n + 1, n + 2)), * ); // Set(1, 2, 3, 4, 5, 6, 7); * ``` * * @since 2.0.0 */export function flatmap<A, I>( fati: (a: A) => ReadonlySet<I>,): (ua: ReadonlySet<A>) => ReadonlySet<I> { return (ua) => { const ti = new Set<I>(); for (const a of ua) { const _ti = fati(a); for (const i of _ti) { ti.add(i); } } return ti; };}
/** * Given a ReadonlySet of ReadonlySet<A>, flatten all of the inner * sets and return a ReadonlySet<A>. * * @example * ```ts * import * as S from "./set.ts"; * * const setOfSets = S.set(S.set(1, 2), S.set(3, 4), S.set(1, 4)); * * const result = S.join(setOfSets); // Set(1, 2, 3, 4) * ``` * * @since 2.0.0 */export function join<A>(uua: ReadonlySet<ReadonlySet<A>>): ReadonlySet<A> { return pipe(uua, flatmap(identity));}
/** * Given a Refinement or Predicate over A and a ReadonlySet<A> return * a new ReadonlySet with only values for which the predicate or * refinement return true. * * @example * ```ts * import * as S from "./set.ts"; * import { pipe } from "./fn.ts"; * * const set = S.set(1, 2, 3, 4, 5); * * const result1 = pipe(set, S.filter(n => n > 2)); // Set(3, 4, 5) * const result2 = pipe(set, S.filter(n => n === 0)); // Set() * ``` * * @since 2.0.0 */export function filter<A, B extends A>( refinement: Refinement<A, B>,): (ua: ReadonlySet<A>) => ReadonlySet<B>;export function filter<A>( predicate: Predicate<A>,): (ua: ReadonlySet<A>) => ReadonlySet<A>;export function filter<A>( predicate: Predicate<A>,): (ua: ReadonlySet<A>) => ReadonlySet<A> { return (ua) => { const _ua = new Set<A>(); for (const a of ua) { if (predicate(a)) { _ua.add(a); } } return _ua; };}
/** * Given a function A -> Option<I> and a ReadonlySet<A> return * a ReadonlySet<I> by applying the function to all values A. Any * Nones will not enter the resultant set while Some<I> values will. * This is effectively filtering and mapping simultaneously. * * @example * ```ts * import * as S from "./set.ts"; * import * as O from "./option.ts"; * import { pipe } from "./fn.ts"; * * const set = S.set("one", "two", "three", "four", "five"); * * const result = pipe( * set, * S.filterMap(s => s.includes('o') ? O.some(s.length) : O.none), * ); // Set(3, 4) * ``` * * @since 2.0.0 */export function filterMap<A, I>( fai: (a: A) => Option<I>,): (ua: ReadonlySet<A>) => ReadonlySet<I> { return (ua) => { const output = new Set<I>(); for (const a of ua) { const value = fai(a); if (O.isSome(value)) { output.add(value.value); } } return output; };}
/** * Given a Predicate or Refinement over A and a ReadonlySet<A> * return a Pair with a first value being a ReadonlySet of values * that return true when applied to the refinement or predicate * and a second value being a ReadonlySet of values that return * false when applied to the predicate. * * @example * ```ts * import * as S from "./set.ts"; * import { pipe } from "./fn.ts"; * * const set = S.set(1, 2, 3, 4); * * const result = pipe( * set, * S.partition(n => n > 2), * ); // [Set(3, 4), Set(1, 2)] * ``` * * @since 2.0.0 */export function partition<A, B extends A>( refinement: Refinement<A, B>,): (ua: ReadonlySet<A>) => Pair<ReadonlySet<B>, ReadonlySet<A>>;export function partition<A>( predicate: Predicate<A>,): (ua: ReadonlySet<A>) => Pair<ReadonlySet<A>, ReadonlySet<A>>;export function partition<A>( predicate: Predicate<A>,): (ua: ReadonlySet<A>) => Pair<ReadonlySet<A>, ReadonlySet<A>> { return (ua) => { const first = new Set<A>(); const second = new Set<A>(); for (const a of ua) { if (predicate(a)) { first.add(a); } else { second.add(a); } } return [first, second]; };}
/** * Given a function A -> Either<J, I> and a ReadonlySet<A> return * a Pair(ReadonlySet<I>, ReadonlySet<J>) by applying every value A * in the set to the partitioning function. * * @example * ```ts * import * as S from "./set.ts"; * import * as E from "./either.ts"; * import { pipe } from "./fn.ts"; * * const set = S.set("one", "two", "three", "four"); * * const result = pipe( * set, * S.partitionMap(s => s.includes('o') ? E.right(s) : E.left(s.length)), * ); // [Set("one", "two", "four"), Set(5)] * ``` * * @since 2.0.0 */export function partitionMap<A, I, J>( fai: (a: A) => Either<J, I>,): (ua: ReadonlySet<A>) => Pair<ReadonlySet<I>, ReadonlySet<J>> { return (ua) => { const first = new Set<I>(); const second = new Set<J>(); for (const a of ua) { const result = fai(a); if (E.isRight(result)) { first.add(result.right); } else { second.add(result.left); } } return [first, second]; };}
/** * Reduce a ReadonlySet<A> to a value O by iterating over * the values of the set and collecting them with the reducing function. * * @example * ```ts * import * as S from "./set.ts"; * import { pipe } from "./fn.ts"; * * const set = S.set(1, 2, 3, 4); * * const result = pipe( * set, * S.fold((previous, current) => previous + current, 0), * ); // 10 * ``` * * @since 2.0.0 */export function fold<A, O>( foao: (o: O, a: A) => O, o: O,): (ua: ReadonlySet<A>) => O { return (ua) => { let out = o; for (const a of ua) { out = foao(out, a); } return out; };}
// This is an unsafe Add for ReadonlySet<A> that violates Readonly contractconst unsafeAdd = <A>(ua: ReadonlySet<A>) => (a: A): Set<A> => { (ua as Set<A>).add(a); return ua as Set<A>;};
/** * Traverse a ReadonlySet<A> value by value, applying a function * A -> V<I>, then collecting all of the I values into ReadonlySet<I> * and returning V<ReadonlySet<I>>. In concrete terms this can take * ReadonlySet<Option<A>> and turn it into Option<ReadonlySet<I>> and * other ADT inversions. * * @example * ```ts * import * as S from "./set.ts"; * import * as O from "./option.ts"; * import { pipe } from "./fn.ts"; * * const traverseOption = S.traverse(O.ApplicableOption); * const invert = traverseOption((o: O.Option<number>) => o); * * const result1 = pipe( * S.set(O.some(1), O.some(2), O.some(3)), * invert, * ); // Some(Set(1, 2, 3)) * const result2 = pipe( * S.set(O.some(1), O.some(2), O.none), * invert, * ); // None * ``` * * @since 2.0.0 */export function traverse<V extends Kind>( A: Applicable<V>,) { return <A, I, J, K, L, M>( favi: (a: A) => $<V, [I, J, K], [L], [M]>, ): (ua: ReadonlySet<A>) => $<V, [ReadonlySet<I>, J, K], [L], [M]> => fold( (vis, a) => pipe(vis, A.map(unsafeAdd), A.apply(favi(a))), A.wrap(init() as Set<I>), );}
/** * Given an instance of Showable<A> return an instance of Showable<ReadonlySet<A>>. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * * const { show } = S.getShowableSet(N.ShowableNumber); * * const result1 = show(S.init()); // "Set([])" * const result2 = show(S.set(1, 2, 3)); // "Set([1, 2, 3])" * ``` * * @since 2.0.0 */export function getShowableSet<A>(S: Showable<A>): Showable<ReadonlySet<A>> { return ({ show: (s) => `Set([${Array.from(s.values()).map(S.show).join(", ")}])`, });}
/** * Given an instance of Comparable<A> return Comparable<ReadonlySet<A>>. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import { pipe } from "./fn.ts"; * * const { compare } = S.getComparableSet(N.ComparableNumber); * * const result1 = compare( * S.set(1, 2, 3))( * S.set(3, 2, 1) * ); // true * const result2 = compare( * S.set(1, 2, 3))( * S.set(1, 2, 3, 4) * ); // false * ``` * * @since 2.0.0 */export function getComparableSet<A>( S: Comparable<A>,): Comparable<ReadonlySet<A>> { const subset = isSubset(S); return fromCompare((second) => (first) => subset(first)(second) && subset(second)(first) );}
/** * Given an instance of Comparable<A> create a Combinable<ReadonlySet<A>> where * combine creates a union of two ReadonlySets. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import * as M from "./combinable.ts"; * import { pipe } from "./fn.ts"; * * const monoid = S.getCombinableSet(N.ComparableNumber); * const combineAll = M.getCombineAll(monoid); * * const result1 = combineAll( * S.set(1, 2, 3), * S.set(4, 5, 6), * S.set(1, 3, 5, 7) * ); // Set(1, 2, 3, 4, 5, 6, 7) * const result3 = combineAll(S.init()); // Set() * ``` * * @since 2.0.0 */export function getCombinableSet<A>( S: Comparable<A>,): Combinable<ReadonlySet<A>> { return fromCombine(union(S));}
/** * Given an instance of Comparable<A> create a Combinable<ReadonlySet<A>> where * combine creates a union of two ReadonlySets. * * @example * ```ts * import * as S from "./set.ts"; * import * as N from "./number.ts"; * import * as M from "./combinable.ts"; * import { pipe } from "./fn.ts"; * * const monoid = S.getInitializableSet(N.ComparableNumber); * const combineAll = M.getCombineAll(monoid); * * const result1 = combineAll( * S.set(1, 2, 3), * S.set(4, 5, 6), * S.set(1, 3, 5, 7) * ); // Set(1, 2, 3, 4, 5, 6, 7) * const result3 = combineAll(S.init()); // Set() * ``` * * @since 2.0.0 */export function getInitializableSet<A>( C: Comparable<A>,): Initializable<ReadonlySet<A>> { return { init: () => new Set(), ...getCombinableSet(C), };}
/** * The canonical implementation of Applicable for ReadonlySet. It contains * the methods wrap, ap, and map. * * @since 2.0.0 */export const ApplicableSet: Applicable<KindReadonlySet> = { apply, map, wrap };
/** * The canonical implementation of Filterable for ReadonlySet. It contains * the methods filter, filterMap, partition, and partitionMap. * * @since 2.0.0 */export const FilterableSet: Filterable<KindReadonlySet> = { filter, filterMap, partition, partitionMap,};
/** * The canonical implementation of Flatmappable for ReadonlySet. It contains * the methods wrap, ap, map, join, and flatmap. * * @since 2.0.0 */export const FlatmappableSet: Flatmappable<KindReadonlySet> = { apply, flatmap, map, wrap,};
/** * The canonical implementation of Foldable for ReadonlySet. It contains * the method fold. * * @since 2.0.0 */export const FoldableSet: Foldable<KindReadonlySet> = { fold };
/** * The canonical implementation of Mappable for ReadonlySet. It contains * the method map. * * @since 2.0.0 */export const MappableSet: Mappable<KindReadonlySet> = { map };
/** * The canonical implementation of Traversable for ReadonlySet. It contains * the methods map, fold, and traverse. * * @since 2.0.0 */export const TraversableSet: Traversable<KindReadonlySet> = { map, fold, traverse,};
/** * @since 2.0.0 */export const WrappableSet: Wrappable<KindReadonlySet> = { wrap };
/** * @since 2.0.0 */export const tap = createTap(FlatmappableSet);
/** * @since 2.0.0 */export const bind = createBind(FlatmappableSet);
/** * @since 2.0.0 */export const bindTo = createBindTo(MappableSet);