import {
  fromOption,
  fromOptionK,
  fromPredicate
} from "./chunk-SEYMJLV6.mjs";
import {
  flap
} from "./chunk-WKK6AYQI.mjs";
import {
  fromEquals
} from "./chunk-YQKF55QL.mjs";
import {
  emptyReadonlyArray,
  head,
  isNonEmpty,
  isNone,
  none,
  some
} from "./chunk-WPJQNT3M.mjs";
import {
  identity,
  pipe
} from "./chunk-ZI34HWXZ.mjs";
import {
  __export
} from "./chunk-QK4PKNB3.mjs";

// src/These.ts
var These_exports = {};
__export(These_exports, {
  ApT: () => ApT,
  Bifunctor: () => Bifunctor,
  Foldable: () => Foldable,
  FromEither: () => FromEither,
  FromThese: () => FromThese,
  Functor: () => Functor,
  Pointed: () => Pointed,
  Traversable: () => Traversable,
  URI: () => URI,
  bimap: () => bimap,
  both: () => both,
  elem: () => elem,
  exists: () => exists,
  flap: () => flap2,
  fold: () => fold,
  foldMap: () => foldMap,
  foldW: () => foldW,
  fromOption: () => fromOption2,
  fromOptionK: () => fromOptionK2,
  fromOptions: () => fromOptions,
  fromPredicate: () => fromPredicate2,
  getApplicative: () => getApplicative,
  getApply: () => getApply,
  getChain: () => getChain,
  getEq: () => getEq,
  getLeft: () => getLeft,
  getLeftOnly: () => getLeftOnly,
  getMonad: () => getMonad,
  getRight: () => getRight,
  getRightOnly: () => getRightOnly,
  getSemigroup: () => getSemigroup,
  getShow: () => getShow,
  isBoth: () => isBoth,
  isLeft: () => isLeft,
  isRight: () => isRight,
  left: () => left,
  leftOrBoth: () => leftOrBoth,
  map: () => map,
  mapLeft: () => mapLeft,
  match: () => match,
  matchW: () => matchW,
  of: () => of,
  reduce: () => reduce,
  reduceRight: () => reduceRight,
  right: () => right,
  rightOrBoth: () => rightOrBoth,
  sequence: () => sequence,
  swap: () => swap,
  these: () => these,
  toTuple: () => toTuple,
  toTuple2: () => toTuple2,
  traverse: () => traverse,
  traverseReadonlyArrayWithIndex: () => traverseReadonlyArrayWithIndex,
  traverseReadonlyNonEmptyArrayWithIndex: () => traverseReadonlyNonEmptyArrayWithIndex
});
var isLeft = (fa) => fa._tag === "Left";
var isRight = (fa) => fa._tag === "Right";
function isBoth(fa) {
  return fa._tag === "Both";
}
function left(left2) {
  return { _tag: "Left", left: left2 };
}
function right(right2) {
  return { _tag: "Right", right: right2 };
}
function both(left2, right2) {
  return { _tag: "Both", left: left2, right: right2 };
}
var matchW = (onLeft, onRight, onBoth) => (fa) => {
  switch (fa._tag) {
    case "Left":
      return onLeft(fa.left);
    case "Right":
      return onRight(fa.right);
    case "Both":
      return onBoth(fa.left, fa.right);
  }
};
var foldW = matchW;
var match = matchW;
var fold = match;
var swap = match(right, left, (e, a) => both(a, e));
function getShow(SE, SA) {
  return {
    show: match(
      (l) => `left(${SE.show(l)})`,
      (a) => `right(${SA.show(a)})`,
      (l, a) => `both(${SE.show(l)}, ${SA.show(a)})`
    )
  };
}
function getEq(EE, EA) {
  return fromEquals(
    (x, y) => isLeft(x) ? isLeft(y) && EE.equals(x.left, y.left) : isRight(x) ? isRight(y) && EA.equals(x.right, y.right) : isBoth(y) && EE.equals(x.left, y.left) && EA.equals(x.right, y.right)
  );
}
function getSemigroup(SE, SA) {
  return {
    concat: (x, y) => isLeft(x) ? isLeft(y) ? left(SE.concat(x.left, y.left)) : isRight(y) ? both(x.left, y.right) : both(SE.concat(x.left, y.left), y.right) : isRight(x) ? isLeft(y) ? both(y.left, x.right) : isRight(y) ? right(SA.concat(x.right, y.right)) : both(y.left, SA.concat(x.right, y.right)) : isLeft(y) ? both(SE.concat(x.left, y.left), x.right) : isRight(y) ? both(x.left, SA.concat(x.right, y.right)) : both(SE.concat(x.left, y.left), SA.concat(x.right, y.right))
  };
}
var getApply = (S) => ({
  URI,
  _E: void 0,
  map: _map,
  ap: (fab, fa) => isLeft(fab) ? isLeft(fa) ? left(S.concat(fab.left, fa.left)) : isRight(fa) ? left(fab.left) : left(S.concat(fab.left, fa.left)) : isRight(fab) ? isLeft(fa) ? left(fa.left) : isRight(fa) ? right(fab.right(fa.right)) : both(fa.left, fab.right(fa.right)) : isLeft(fa) ? left(S.concat(fab.left, fa.left)) : isRight(fa) ? both(fab.left, fab.right(fa.right)) : both(S.concat(fab.left, fa.left), fab.right(fa.right))
});
function getApplicative(S) {
  const A = getApply(S);
  return {
    URI,
    _E: void 0,
    map: _map,
    ap: A.ap,
    of
  };
}
function getChain(S) {
  const A = getApply(S);
  const chain = (ma, f) => {
    if (isLeft(ma)) {
      return ma;
    }
    if (isRight(ma)) {
      return f(ma.right);
    }
    const fb = f(ma.right);
    return isLeft(fb) ? left(S.concat(ma.left, fb.left)) : isRight(fb) ? both(ma.left, fb.right) : both(S.concat(ma.left, fb.left), fb.right);
  };
  return {
    URI,
    _E: void 0,
    map: _map,
    ap: A.ap,
    chain
  };
}
function getMonad(S) {
  const C = getChain(S);
  return {
    URI,
    _E: void 0,
    map: _map,
    of,
    ap: C.ap,
    chain: C.chain,
    throwError: left
  };
}
function getLeft(fa) {
  return isLeft(fa) ? some(fa.left) : isRight(fa) ? none : some(fa.left);
}
function getRight(fa) {
  return isLeft(fa) ? none : isRight(fa) ? some(fa.right) : some(fa.right);
}
function leftOrBoth(e) {
  return (ma) => isNone(ma) ? left(e) : both(e, ma.value);
}
function rightOrBoth(a) {
  return (me) => isNone(me) ? right(a) : both(me.value, a);
}
function getLeftOnly(fa) {
  return isLeft(fa) ? some(fa.left) : none;
}
function getRightOnly(fa) {
  return isRight(fa) ? some(fa.right) : none;
}
var fromOptions = (fe, fa) => isNone(fe) ? isNone(fa) ? none : some(right(fa.value)) : isNone(fa) ? some(left(fe.value)) : some(both(fe.value, fa.value));
var _map = (fa, f) => pipe(fa, map(f));
var _bimap = (fa, f, g) => pipe(fa, bimap(f, g));
var _mapLeft = (fa, f) => pipe(fa, mapLeft(f));
var _reduce = (fa, b, f) => pipe(fa, reduce(b, f));
var _foldMap = (M) => {
  const foldMapM = foldMap(M);
  return (fa, f) => pipe(fa, foldMapM(f));
};
var _reduceRight = (fa, b, f) => pipe(fa, reduceRight(b, f));
var _traverse = (F) => {
  const traverseF = traverse(F);
  return (ta, f) => pipe(ta, traverseF(f));
};
var bimap = (f, g) => (fa) => isLeft(fa) ? left(f(fa.left)) : isRight(fa) ? right(g(fa.right)) : both(f(fa.left), g(fa.right));
var mapLeft = (f) => (fa) => isLeft(fa) ? left(f(fa.left)) : isBoth(fa) ? both(f(fa.left), fa.right) : fa;
var map = (f) => (fa) => isLeft(fa) ? fa : isRight(fa) ? right(f(fa.right)) : both(fa.left, f(fa.right));
var reduce = (b, f) => (fa) => isLeft(fa) ? b : f(b, fa.right);
var foldMap = (M) => (f) => (fa) => isLeft(fa) ? M.empty : f(fa.right);
var reduceRight = (b, f) => (fa) => isLeft(fa) ? b : f(fa.right, b);
var traverse = (F) => (f) => (ta) => isLeft(ta) ? F.of(ta) : isRight(ta) ? F.map(f(ta.right), right) : F.map(f(ta.right), (b) => both(ta.left, b));
var sequence = (F) => (ta) => {
  return isLeft(ta) ? F.of(ta) : isRight(ta) ? F.map(ta.right, right) : F.map(ta.right, (b) => both(ta.left, b));
};
var of = right;
var URI = "These";
var Functor = {
  URI,
  map: _map
};
var flap2 = /* @__PURE__ */ flap(Functor);
var Pointed = {
  URI,
  of
};
var Bifunctor = {
  URI,
  bimap: _bimap,
  mapLeft: _mapLeft
};
var FromThese = {
  URI,
  fromThese: identity
};
var Foldable = {
  URI,
  reduce: _reduce,
  foldMap: _foldMap,
  reduceRight: _reduceRight
};
var Traversable = {
  URI,
  map: _map,
  reduce: _reduce,
  foldMap: _foldMap,
  reduceRight: _reduceRight,
  traverse: _traverse,
  sequence
};
var FromEither = {
  URI,
  fromEither: identity
};
var fromPredicate2 = /* @__PURE__ */ fromPredicate(FromEither);
var fromOption2 = /* @__PURE__ */ fromOption(FromEither);
var fromOptionK2 = /* @__PURE__ */ fromOptionK(FromEither);
var elem = (E) => (a) => (ma) => isLeft(ma) ? false : E.equals(a, ma.right);
var exists = (predicate) => (ma) => isLeft(ma) ? false : predicate(ma.right);
var toTuple2 = (e, a) => (fa) => isLeft(fa) ? [fa.left, a()] : isRight(fa) ? [e(), fa.right] : [fa.left, fa.right];
var toTuple = (e, a) => toTuple2(
  () => e,
  () => a
);
var ApT = /* @__PURE__ */ of(emptyReadonlyArray);
var traverseReadonlyNonEmptyArrayWithIndex = (S) => (f) => (as) => {
  let e = none;
  const t = f(0, head(as));
  if (isLeft(t)) {
    return t;
  }
  if (isBoth(t)) {
    e = some(t.left);
  }
  const out = [t.right];
  for (let i = 1; i < as.length; i++) {
    const t2 = f(i, as[i]);
    if (isLeft(t2)) {
      return t2;
    }
    if (isBoth(t2)) {
      e = isNone(e) ? some(t2.left) : some(S.concat(e.value, t2.left));
    }
    out.push(t2.right);
  }
  return isNone(e) ? right(out) : both(e.value, out);
};
var traverseReadonlyArrayWithIndex = (S) => (f) => {
  const g = traverseReadonlyNonEmptyArrayWithIndex(S)(f);
  return (as) => isNonEmpty(as) ? g(as) : ApT;
};
var these = {
  URI,
  map: _map,
  bimap: _bimap,
  mapLeft: _mapLeft,
  reduce: _reduce,
  foldMap: _foldMap,
  reduceRight: _reduceRight,
  traverse: _traverse,
  sequence
};

export {
  isLeft,
  isRight,
  isBoth,
  left,
  right,
  both,
  matchW,
  foldW,
  match,
  fold,
  swap,
  getShow,
  getEq,
  getSemigroup,
  getApply,
  getApplicative,
  getChain,
  getMonad,
  getLeft,
  getRight,
  leftOrBoth,
  rightOrBoth,
  getLeftOnly,
  getRightOnly,
  fromOptions,
  bimap,
  mapLeft,
  map,
  reduce,
  foldMap,
  reduceRight,
  traverse,
  sequence,
  of,
  URI,
  Functor,
  flap2 as flap,
  Pointed,
  Bifunctor,
  FromThese,
  Foldable,
  Traversable,
  FromEither,
  fromPredicate2 as fromPredicate,
  fromOption2 as fromOption,
  fromOptionK2 as fromOptionK,
  elem,
  exists,
  toTuple2,
  toTuple,
  ApT,
  traverseReadonlyNonEmptyArrayWithIndex,
  traverseReadonlyArrayWithIndex,
  these,
  These_exports
};
