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"