import {
  elem,
  every,
  foldMap,
  getEq,
  getShow,
  isSubset,
  reduce,
  reduceRight,
  some
} from "./chunk-V323UDIY.mjs";
import {
  separated
} from "./chunk-RAKKSTP2.mjs";
import {
  identity
} from "./chunk-ZI34HWXZ.mjs";
import {
  __export
} from "./chunk-QK4PKNB3.mjs";

// src/Set.ts
var Set_exports = {};
__export(Set_exports, {
  chain: () => chain,
  compact: () => compact,
  difference: () => difference,
  elem: () => elem2,
  empty: () => empty,
  every: () => every2,
  filter: () => filter,
  filterMap: () => filterMap,
  foldMap: () => foldMap2,
  fromArray: () => fromArray,
  getDifferenceMagma: () => getDifferenceMagma,
  getEq: () => getEq2,
  getIntersectionSemigroup: () => getIntersectionSemigroup,
  getShow: () => getShow2,
  getUnionMonoid: () => getUnionMonoid,
  getUnionSemigroup: () => getUnionSemigroup,
  insert: () => insert,
  intersection: () => intersection,
  isEmpty: () => isEmpty,
  isSubset: () => isSubset2,
  map: () => map,
  partition: () => partition,
  partitionMap: () => partitionMap,
  reduce: () => reduce2,
  reduceRight: () => reduceRight2,
  remove: () => remove,
  separate: () => separate,
  singleton: () => singleton,
  size: () => size,
  some: () => some2,
  subset: () => subset,
  toArray: () => toArray,
  toggle: () => toggle,
  union: () => union
});
var getShow2 = getShow;
var getEq2 = getEq;
function map(E) {
  const elemE = elem2(E);
  return (f) => (set) => {
    const r = /* @__PURE__ */ new Set();
    set.forEach((e) => {
      const v = f(e);
      if (!elemE(v, r)) {
        r.add(v);
      }
    });
    return r;
  };
}
function chain(E) {
  const elemE = elem2(E);
  return (f) => (set) => {
    const r = /* @__PURE__ */ new Set();
    set.forEach((e) => {
      f(e).forEach((e2) => {
        if (!elemE(e2, r)) {
          r.add(e2);
        }
      });
    });
    return r;
  };
}
function filter(predicate) {
  return (set) => {
    const values = set.values();
    let e;
    const r = /* @__PURE__ */ new Set();
    while (!(e = values.next()).done) {
      const a = e.value;
      if (predicate(a)) {
        r.add(a);
      }
    }
    return r;
  };
}
function partition(predicate) {
  return (set) => {
    const values = set.values();
    let e;
    const right = /* @__PURE__ */ new Set();
    const left = /* @__PURE__ */ new Set();
    while (!(e = values.next()).done) {
      const a = e.value;
      if (predicate(a)) {
        right.add(a);
      } else {
        left.add(a);
      }
    }
    return separated(left, right);
  };
}
function union(E) {
  const elemE = elem2(E);
  return (me, that) => {
    if (that === void 0) {
      const unionE = union(E);
      return (that2) => unionE(me, that2);
    }
    if (isEmpty(me)) {
      return that;
    }
    if (isEmpty(that)) {
      return me;
    }
    const r = new Set(me);
    that.forEach((e) => {
      if (!elemE(e, r)) {
        r.add(e);
      }
    });
    return r;
  };
}
function intersection(E) {
  const elemE = elem2(E);
  return (me, that) => {
    if (that === void 0) {
      const intersectionE = intersection(E);
      return (that2) => intersectionE(that2, me);
    }
    if (isEmpty(me) || isEmpty(that)) {
      return /* @__PURE__ */ new Set();
    }
    const r = /* @__PURE__ */ new Set();
    me.forEach((e) => {
      if (elemE(e, that)) {
        r.add(e);
      }
    });
    return r;
  };
}
function partitionMap(EB, EC) {
  return (f) => (set) => {
    const values = set.values();
    let e;
    const left = /* @__PURE__ */ new Set();
    const right = /* @__PURE__ */ new Set();
    const hasB = elem2(EB);
    const hasC = elem2(EC);
    while (!(e = values.next()).done) {
      const v = f(e.value);
      switch (v._tag) {
        case "Left":
          if (!hasB(v.left, left)) {
            left.add(v.left);
          }
          break;
        case "Right":
          if (!hasC(v.right, right)) {
            right.add(v.right);
          }
          break;
      }
    }
    return separated(left, right);
  };
}
function difference(E) {
  const elemE = elem2(E);
  return (me, that) => {
    if (that === void 0) {
      const differenceE = difference(E);
      return (that2) => differenceE(that2, me);
    }
    return filter((a) => !elemE(a, that))(me);
  };
}
var getUnionSemigroup = (E) => ({
  concat: union(E)
});
var getUnionMonoid = (E) => ({
  concat: getUnionSemigroup(E).concat,
  empty: /* @__PURE__ */ new Set()
});
var getIntersectionSemigroup = (E) => ({
  concat: intersection(E)
});
var getDifferenceMagma = (E) => ({
  concat: difference(E)
});
var reduce2 = reduce;
var foldMap2 = foldMap;
var reduceRight2 = reduceRight;
var singleton = (a) => /* @__PURE__ */ new Set([a]);
function insert(E) {
  const elemE = elem2(E);
  return (a) => (set) => {
    if (!elemE(a)(set)) {
      const r = new Set(set);
      r.add(a);
      return r;
    } else {
      return set;
    }
  };
}
var remove = (E) => (a) => (set) => filter((ax) => !E.equals(a, ax))(set);
var toggle = (E) => {
  const elemE = elem2(E);
  const removeE = remove(E);
  const insertE = insert(E);
  return (a) => (set) => (elemE(a, set) ? removeE : insertE)(a)(set);
};
var fromArray = (E) => (as) => {
  const len = as.length;
  const out = /* @__PURE__ */ new Set();
  const has = elem2(E);
  for (let i = 0; i < len; i++) {
    const a = as[i];
    if (!has(a, out)) {
      out.add(a);
    }
  }
  return out;
};
var compact = (E) => filterMap(E)(identity);
function separate(EE, EA) {
  return (fa) => {
    const elemEE = elem2(EE);
    const elemEA = elem2(EA);
    const left = /* @__PURE__ */ new Set();
    const right = /* @__PURE__ */ new Set();
    fa.forEach((e) => {
      switch (e._tag) {
        case "Left":
          if (!elemEE(e.left, left)) {
            left.add(e.left);
          }
          break;
        case "Right":
          if (!elemEA(e.right, right)) {
            right.add(e.right);
          }
          break;
      }
    });
    return separated(left, right);
  };
}
function filterMap(E) {
  const elemE = elem2(E);
  return (f) => (fa) => {
    const r = /* @__PURE__ */ new Set();
    fa.forEach((a) => {
      const ob = f(a);
      if (ob._tag === "Some" && !elemE(ob.value, r)) {
        r.add(ob.value);
      }
    });
    return r;
  };
}
var empty = /* @__PURE__ */ new Set();
var isEmpty = (set) => set.size === 0;
var size = (set) => set.size;
var some2 = some;
var every2 = every;
var isSubset2 = isSubset;
var elem2 = elem;
var toArray = (O) => (set) => {
  const out = [];
  set.forEach((e) => out.push(e));
  return out.sort(O.compare);
};
var subset = isSubset;

export {
  getShow2 as getShow,
  getEq2 as getEq,
  map,
  chain,
  filter,
  partition,
  union,
  intersection,
  partitionMap,
  difference,
  getUnionSemigroup,
  getUnionMonoid,
  getIntersectionSemigroup,
  getDifferenceMagma,
  reduce2 as reduce,
  foldMap2 as foldMap,
  reduceRight2 as reduceRight,
  singleton,
  insert,
  remove,
  toggle,
  fromArray,
  compact,
  separate,
  filterMap,
  empty,
  isEmpty,
  size,
  some2 as some,
  every2 as every,
  isSubset2 as isSubset,
  elem2 as elem,
  toArray,
  subset,
  Set_exports
};
