import { Option as OptionLegacy } from "@effect-ts/core" import { flow } from "./Function.js" import { Option } from "./Prelude.js" import { filter_, filterMap, filterMap_, fromArray as fromArrayOriginal, insert as insertOriginal, insert_ as insert_Original, map, map_, reduce, reduce_, remove, remove_, Set, toArray as toArrayOriginal } from "./Set.js" export interface NonEmptyBrand { readonly NonEmpty: unique symbol } function convertOpt(a: Option) { return a.isSome() ? OptionLegacy.some(a.value) : OptionLegacy.none } /** * @tsplus type ets/NESet */ export type NonEmptySet = Set & NonEmptyBrand function make_(ord: Ord, eq_?: Equal) { const eq = eq_ ?? > { equals: (x, y) => ord.compare(x, y) === 0 } const fromArray_ = fromArrayOriginal(eq) const fromArray = flow(fromArray_, fromSet) const fromNonEmptyArray = (arr: NonEmptyReadonlyArray) => fromArray_(arr) as NonEmptySet const concat_ = (set: NonEmptySet, it: Iterable) => fromArray([...set, ...it]) const insert__ = insertOriginal(eq) const insert: (a: A) => (set: NonEmptySet) => NonEmptySet = insert__ as any const insert_: (set: NonEmptySet, a: A) => NonEmptySet = insert_Original as any function replace_(set: NonEmptySet, a: A) { return (filter_(set, x => !eq.equals(x, a)) >= insert__(a)) as NonEmptySet } const toArray__ = toArrayOriginal(ord) function toArray(s: NonEmptySet) { return toArray__(s) as NonEmptyReadonlyArray } const remove__ = remove(eq) const filterMap__ = filterMap(eq) return { insert, insert_, remove: (a: A) => flow(remove__(a), fromSet), remove_: flow(remove_(eq), fromSet), reduce: reduce(ord), reduce_: reduce_(ord), replace: (a: A) => (set: NonEmptySet) => replace_(set, a), replace_, toArray, fromArray, fromNonEmptyArray, from: (it: Iterable) => fromArray([...it]), of: (a: A) => new Set([a]) as unknown as NonEmptySet, concat_, concat: (it: Iterable) => (set: NonEmptySet) => concat_(set, it), // A and B the same, useful when editing elements. map: map(eq) as unknown as ( f: (x: A) => A ) => (set: NonEmptySet) => NonEmptySet, map_: map_(eq) as unknown as ( set: NonEmptySet, f: (x: A) => A ) => NonEmptySet, filterMap: (f: (a: A) => Option) => flow(filterMap__(a => convertOpt(f(a))), fromSet), filterMap_: flow(filterMap_(eq), fromSet) } // TODO: extend } class Wrapper { wrapped(ord: Ord, eq?: Equal) { return make_(ord, eq) } } export interface NonEmptySetSchemaExtensions extends ReturnType["wrapped"]> {} export const make: ( ord: Ord, eq?: Equal ) => NonEmptySetSchemaExtensions = make_ export function fromSet(set: Set) { if (set.size > 0) { return Option.some(set as NonEmptySet) } else { return Option.none } } // TODO export * from "@effect-ts/core/Collections/Immutable/Set"