text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.apS = exports.bind = exports.bindTo = exports.getRefinement = exports.exists = exports.elem = exports.option = exports.MonadThrow = exports.Witherable = exports.Traversable = exports.Filterable = exports.Compactable = exports.Extend = exports.Alternative = exports.Alt = exports.Foldable = exports.Monad = exports.Applicative = exports.Functor = exports.getMonoid = exports.getLastMonoid = exports.getFirstMonoid = exports.getApplyMonoid = exports.getApplySemigroup = exports.getOrd = exports.getEq = exports.getShow = exports.URI = exports.wilt = exports.wither = exports.sequence = exports.traverse = exports.partitionMap = exports.partition = exports.filterMap = exports.filter = exports.separate = exports.compact = exports.reduceRight = exports.foldMap = exports.reduce = exports.duplicate = exports.extend = exports.throwError = exports.zero = exports.alt = exports.flatten = exports.chainFirst = exports.chain = exports.of = exports.apSecond = exports.apFirst = exports.ap = exports.map = exports.mapNullable = exports.getOrElse = exports.getOrElseW = exports.toUndefined = exports.toNullable = exports.fold = exports.fromEither = exports.getRight = exports.getLeft = exports.tryCatch = exports.fromPredicate = exports.fromNullable = exports.some = exports.none = exports.isNone = exports.isSome = void 0;
  var function_1 = require("./function");
  // -------------------------------------------------------------------------------------
  // guards
  // -------------------------------------------------------------------------------------
  /**
   * Returns `true` if the option is an instance of `Some`, `false` otherwise
   *
   * @example
   * import { some, none, isSome } from 'fp-ts/Option'
   *
   * assert.strictEqual(isSome(some(1)), true)
   * assert.strictEqual(isSome(none), false)
   *
   * @category guards
   * @since 2.0.0
   */
  exports.isSome = function (fa) { return fa._tag === 'Some'; };
  /**
   * Returns `true` if the option is `None`, `false` otherwise
   *
   * @example
   * import { some, none, isNone } from 'fp-ts/Option'
   *
   * assert.strictEqual(isNone(some(1)), false)
   * assert.strictEqual(isNone(none), true)
   *
   * @category guards
   * @since 2.0.0
   */
  exports.isNone = function (fa) { return fa._tag === 'None'; };
  // -------------------------------------------------------------------------------------
  // constructors
  // -------------------------------------------------------------------------------------
  /**
   * @category constructors
   * @since 2.0.0
   */
  exports.none = { _tag: 'None' };
  /**
   * @category constructors
   * @since 2.0.0
   */
  exports.some = function (a) { return ({ _tag: 'Some', value: a }); };
  /**
   * Constructs a new `Option` from a nullable type. If the value is `null` or `undefined`, returns `None`, otherwise
   * returns the value wrapped in a `Some`
   *
   * @example
   * import { none, some, fromNullable } from 'fp-ts/Option'
   *
   * assert.deepStrictEqual(fromNullable(undefined), none)
   * assert.deepStrictEqual(fromNullable(null), none)
   * assert.deepStrictEqual(fromNullable(1), some(1))
   *
   * @category constructors
   * @since 2.0.0
   */
  function fromNullable(a) {
      return a == null ? exports.none : exports.some(a);
  }
  exports.fromNullable = fromNullable;
  function fromPredicate(predicate) {
      return function (a) { return (predicate(a) ? exports.some(a) : exports.none); };
  }
  exports.fromPredicate = fromPredicate;
  /**
   * Transforms an exception into an `Option`. If `f` throws, returns `None`, otherwise returns the output wrapped in
   * `Some`
   *
   * @example
   * import { none, some, tryCatch } from 'fp-ts/Option'
   *
   * assert.deepStrictEqual(
   *   tryCatch(() => {
   *     throw new Error()
   *   }),
   *   none
   * )
   * assert.deepStrictEqual(tryCatch(() => 1), some(1))
   *
   * @category constructors
   * @since 2.0.0
   */
  function tryCatch(f) {
      try {
          return exports.some(f());
      }
      catch (e) {
          return exports.none;
      }
  }
  exports.tryCatch = tryCatch;
  /**
   * Returns an `E` value if possible
   *
   * @category constructors
   * @since 2.0.0
   */
  function getLeft(ma) {
      return ma._tag === 'Right' ? exports.none : exports.some(ma.left);
  }
  exports.getLeft = getLeft;
  /**
   * Returns an `A` value if possible
   *
   * @category constructors
   * @since 2.0.0
   */
  function getRight(ma) {
      return ma._tag === 'Left' ? exports.none : exports.some(ma.right);
  }
  exports.getRight = getRight;
  /**
   * @category constructors
   * @since 2.0.0
   */
  exports.fromEither = function (ma) { return (ma._tag === 'Left' ? exports.none : exports.some(ma.right)); };
  // -------------------------------------------------------------------------------------
  // destructors
  // -------------------------------------------------------------------------------------
  /**
   * Takes a default value, a function, and an `Option` value, if the `Option` value is `None` the default value is
   * returned, otherwise the function is applied to the value inside the `Some` and the result is returned.
   *
   * @example
   * import { some, none, fold } from 'fp-ts/Option'
   * import { pipe } from 'fp-ts/function'
   *
   * assert.strictEqual(
   *   pipe(
   *     some(1),
   *     fold(() => 'a none', a => `a some containing ${a}`)
   *   ),
   *   'a some containing 1'
   * )
   *
   * assert.strictEqual(
   *   pipe(
   *     none,
   *     fold(() => 'a none', a => `a some containing ${a}`)
   *   ),
   *   'a none'
   * )
   *
   * @category destructors
   * @since 2.0.0
   */
  function fold(onNone, onSome) {
      return function (ma) { return (exports.isNone(ma) ? onNone() : onSome(ma.value)); };
  }
  exports.fold = fold;
  /**
   * Extracts the value out of the structure, if it exists. Otherwise returns `null`.
   *
   * @example
   * import { some, none, toNullable } from 'fp-ts/Option'
   * import { pipe } from 'fp-ts/function'
   *
   * assert.strictEqual(
   *   pipe(
   *     some(1),
   *     toNullable
   *   ),
   *   1
   * )
   * assert.strictEqual(
   *   pipe(
   *     none,
   *     toNullable
   *   ),
   *   null
   * )
   *
   * @category destructors
   * @since 2.0.0
   */
  function toNullable(ma) {
      return exports.isNone(ma) ? null : ma.value;
  }
  exports.toNullable = toNullable;
  /**
   * Extracts the value out of the structure, if it exists. Otherwise returns `undefined`.
   *
   * @example
   * import { some, none, toUndefined } from 'fp-ts/Option'
   * import { pipe } from 'fp-ts/function'
   *
   * assert.strictEqual(
   *   pipe(
   *     some(1),
   *     toUndefined
   *   ),
   *   1
   * )
   * assert.strictEqual(
   *   pipe(
   *     none,
   *     toUndefined
   *   ),
   *   undefined
   * )
   *
   * @category destructors
   * @since 2.0.0
   */
  function toUndefined(ma) {
      return exports.isNone(ma) ? undefined : ma.value;
  }
  exports.toUndefined = toUndefined;
  /**
   * Less strict version of [`getOrElse`](#getOrElse).
   *
   * @category destructors
   * @since 2.6.0
   */
  exports.getOrElseW = function (onNone) { return function (ma) { return (exports.isNone(ma) ? onNone() : ma.value); }; };
  /**
   * Extracts the value out of the structure, if it exists. Otherwise returns the given default value
   *
   * @example
   * import { some, none, getOrElse } from 'fp-ts/Option'
   * import { pipe } from 'fp-ts/function'
   *
   * assert.strictEqual(
   *   pipe(
   *     some(1),
   *     getOrElse(() => 0)
   *   ),
   *   1
   * )
   * assert.strictEqual(
   *   pipe(
   *     none,
   *     getOrElse(() => 0)
   *   ),
   *   0
   * )
   *
   * @category destructors
   * @since 2.0.0
   */
  exports.getOrElse = exports.getOrElseW;
  // -------------------------------------------------------------------------------------
  // combinators
  // -------------------------------------------------------------------------------------
  /**
   * This is `chain` + `fromNullable`, useful when working with optional values
   *
   * @example
   * import { some, none, fromNullable, mapNullable } from 'fp-ts/Option'
   * import { pipe } from 'fp-ts/function'
   *
   * interface Employee {
   *   company?: {
   *     address?: {
   *       street?: {
   *         name?: string
   *       }
   *     }
   *   }
   * }
   *
   * const employee1: Employee = { company: { address: { street: { name: 'high street' } } } }
   *
   * assert.deepStrictEqual(
   *   pipe(
   *     fromNullable(employee1.company),
   *     mapNullable(company => company.address),
   *     mapNullable(address => address.street),
   *     mapNullable(street => street.name)
   *   ),
   *   some('high street')
   * )
   *
   * const employee2: Employee = { company: { address: { street: {} } } }
   *
   * assert.deepStrictEqual(
   *   pipe(
   *     fromNullable(employee2.company),
   *     mapNullable(company => company.address),
   *     mapNullable(address => address.street),
   *     mapNullable(street => street.name)
   *   ),
   *   none
   * )
   *
   * @category combinators
   * @since 2.0.0
   */
  function mapNullable(f) {
      return function (ma) { return (exports.isNone(ma) ? exports.none : fromNullable(f(ma.value))); };
  }
  exports.mapNullable = mapNullable;
  // -------------------------------------------------------------------------------------
  // non-pipeables
  // -------------------------------------------------------------------------------------
  var map_ = function (fa, f) { return (exports.isNone(fa) ? exports.none : exports.some(f(fa.value))); };
  var ap_ = function (fab, fa) { return (exports.isNone(fab) ? exports.none : exports.isNone(fa) ? exports.none : exports.some(fab.value(fa.value))); };
  var chain_ = function (ma, f) { return (exports.isNone(ma) ? exports.none : f(ma.value)); };
  var reduce_ = function (fa, b, f) { return (exports.isNone(fa) ? b : f(b, fa.value)); };
  var foldMap_ = function (M) { return function (fa, f) { return (exports.isNone(fa) ? M.empty : f(fa.value)); }; };
  var reduceRight_ = function (fa, b, f) { return (exports.isNone(fa) ? b : f(fa.value, b)); };
  var traverse_ = function (F) { return function (ta, f) {
      return exports.isNone(ta) ? F.of(exports.none) : F.map(f(ta.value), exports.some);
  }; };
  var alt_ = function (fa, that) { return (exports.isNone(fa) ? that() : fa); };
  var filter_ = function (fa, predicate) {
      return exports.isNone(fa) ? exports.none : predicate(fa.value) ? fa : exports.none;
  };
  var filterMap_ = function (ma, f) { return (exports.isNone(ma) ? exports.none : f(ma.value)); };
  var extend_ = function (wa, f) { return (exports.isNone(wa) ? exports.none : exports.some(f(wa))); };
  var partition_ = function (fa, predicate) {
      return {
          left: filter_(fa, function (a) { return !predicate(a); }),
          right: filter_(fa, predicate)
      };
  };
  var partitionMap_ = function (fa, f) { return exports.separate(map_(fa, f)); };
  var wither_ = function (F) { return function (fa, f) {
      return exports.isNone(fa) ? F.of(exports.none) : f(fa.value);
  }; };
  var wilt_ = function (F) { return function (fa, f) {
      var o = map_(fa, function (a) {
          return F.map(f(a), function (e) { return ({
              left: getLeft(e),
              right: getRight(e)
          }); });
      });
      return exports.isNone(o)
          ? F.of({
              left: exports.none,
              right: exports.none
          })
          : o.value;
  }; };
  // -------------------------------------------------------------------------------------
  // pipeables
  // -------------------------------------------------------------------------------------
  /**
   * @category Functor
   * @since 2.0.0
   */
  exports.map = function (f) { return function (fa) { return map_(fa, f); }; };
  /**
   * Apply a function to an argument under a type constructor.
   *
   * @category Apply
   * @since 2.0.0
   */
  exports.ap = function (fa) { return function (fab) { return ap_(fab, fa); }; };
  /**
   * Combine two effectful actions, keeping only the result of the first.
   *
   * @category Apply
   * @since 2.0.0
   */
  exports.apFirst = function (fb) {
      return function_1.flow(exports.map(function (a) { return function () { return a; }; }), exports.ap(fb));
  };
  /**
   * Combine two effectful actions, keeping only the result of the second.
   *
   * @category Apply
   * @since 2.0.0
   */
  exports.apSecond = function (fb) {
      return function_1.flow(exports.map(function () { return function (b) { return b; }; }), exports.ap(fb));
  };
  /**
   * @category Applicative
   * @since 2.7.0
   */
  exports.of = exports.some;
  /**
   * Composes computations in sequence, using the return value of one computation to determine the next computation.
   *
   * @category Monad
   * @since 2.0.0
   */
  exports.chain = function (f) { return function (ma) { return chain_(ma, f); }; };
  /**
   * Composes computations in sequence, using the return value of one computation to determine the next computation and
   * keeping only the result of the first.
   *
   * @category Monad
   * @since 2.0.0
   */
  exports.chainFirst = function (f) {
      return exports.chain(function (a) {
          return function_1.pipe(f(a), exports.map(function () { return a; }));
      });
  };
  /**
   * @category Monad
   * @since 2.0.0
   */
  exports.flatten = 
  /*#__PURE__*/
  exports.chain(function_1.identity);
  /**
   * Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to
   * types of kind `* -> *`.
   *
   * In case of `Option` returns the left-most non-`None` value.
   *
   * @example
   * import * as O from 'fp-ts/Option'
   * import { pipe } from 'fp-ts/function'
   *
   * assert.deepStrictEqual(
   *   pipe(
   *     O.some('a'),
   *     O.alt(() => O.some('b'))
   *   ),
   *   O.some('a')
   * )
   * assert.deepStrictEqual(
   *   pipe(
   *     O.none,
   *     O.alt(() => O.some('b'))
   *   ),
   *   O.some('b')
   * )
   *
   * @category Alt
   * @since 2.0.0
   */
  exports.alt = function (that) { return function (fa) { return alt_(fa, that); }; };
  /**
   * @category Alternative
   * @since 2.7.0
   */
  exports.zero = function () { return exports.none; };
  /**
   * @category MonadThrow
   * @since 2.7.0
   */
  exports.throwError = function () { return exports.none; };
  /**
   * @category Extend
   * @since 2.0.0
   */
  exports.extend = function (f) { return function (ma) { return extend_(ma, f); }; };
  /**
   * @category Extend
   * @since 2.0.0
   */
  exports.duplicate = 
  /*#__PURE__*/
  exports.extend(function_1.identity);
  /**
   * @category Foldable
   * @since 2.0.0
   */
  exports.reduce = function (b, f) { return function (fa) { return reduce_(fa, b, f); }; };
  /**
   * @category Foldable
   * @since 2.0.0
   */
  exports.foldMap = function (M) {
      var foldMapM = foldMap_(M);
      return function (f) { return function (fa) { return foldMapM(fa, f); }; };
  };
  /**
   * @category Foldable
   * @since 2.0.0
   */
  exports.reduceRight = function (b, f) { return function (fa) {
      return reduceRight_(fa, b, f);
  }; };
  /**
   * @category Compactable
   * @since 2.0.0
   */
  exports.compact = exports.flatten;
  var defaultSeparate = { left: exports.none, right: exports.none };
  /**
   * @category Compactable
   * @since 2.0.0
   */
  exports.separate = function (ma) {
      var o = map_(ma, function (e) { return ({
          left: getLeft(e),
          right: getRight(e)
      }); });
      return exports.isNone(o) ? defaultSeparate : o.value;
  };
  /**
   * @category Filterable
   * @since 2.0.0
   */
  exports.filter = function (predicate) { return function (fa) { return filter_(fa, predicate); }; };
  /**
   * @category Filterable
   * @since 2.0.0
   */
  exports.filterMap = function (f) { return function (fa) {
      return filterMap_(fa, f);
  }; };
  /**
   * @category Filterable
   * @since 2.0.0
   */
  exports.partition = function (predicate) { return function (fa) { return partition_(fa, predicate); }; };
  /**
   * @category Filterable
   * @since 2.0.0
   */
  exports.partitionMap = function (f) { return function (fa) { return partitionMap_(fa, f); }; };
  /**
   * @category Traversable
   * @since 2.6.3
   */
  exports.traverse = function (F) {
      var traverseF = traverse_(F);
      return function (f) { return function (ta) { return traverseF(ta, f); }; };
  };
  /**
   * @category Traversable
   * @since 2.6.3
   */
  exports.sequence = function (F) { return function (ta) {
      return exports.isNone(ta) ? F.of(exports.none) : F.map(ta.value, exports.some);
  }; };
  /**
   * @category Witherable
   * @since 2.6.5
   */
  exports.wither = function (F) {
      var witherF = wither_(F);
      return function (f) { return function (ta) { return witherF(ta, f); }; };
  };
  /**
   * @category Witherable
   * @since 2.6.5
   */
  exports.wilt = function (F) {
      var wiltF = wilt_(F);
      return function (f) { return function (ta) { return wiltF(ta, f); }; };
  };
  // -------------------------------------------------------------------------------------
  // instances
  // -------------------------------------------------------------------------------------
  /**
   * @category instances
   * @since 2.0.0
   */
  exports.URI = 'Option';
  /**
   * @category instances
   * @since 2.0.0
   */
  function getShow(S) {
      return {
          show: function (ma) { return (exports.isNone(ma) ? 'none' : "some(" + S.show(ma.value) + ")"); }
      };
  }
  exports.getShow = getShow;
  /**
   * @example
   * import { none, some, getEq } from 'fp-ts/Option'
   * import { eqNumber } from 'fp-ts/Eq'
   *
   * const E = getEq(eqNumber)
   * assert.strictEqual(E.equals(none, none), true)
   * assert.strictEqual(E.equals(none, some(1)), false)
   * assert.strictEqual(E.equals(some(1), none), false)
   * assert.strictEqual(E.equals(some(1), some(2)), false)
   * assert.strictEqual(E.equals(some(1), some(1)), true)
   *
   * @category instances
   * @since 2.0.0
   */
  function getEq(E) {
      return {
          equals: function (x, y) { return x === y || (exports.isNone(x) ? exports.isNone(y) : exports.isNone(y) ? false : E.equals(x.value, y.value)); }
      };
  }
  exports.getEq = getEq;
  /**
   * The `Ord` instance allows `Option` values to be compared with
   * `compare`, whenever there is an `Ord` instance for
   * the type the `Option` contains.
   *
   * `None` is considered to be less than any `Some` value.
   *
   *
   * @example
   * import { none, some, getOrd } from 'fp-ts/Option'
   * import { ordNumber } from 'fp-ts/Ord'
   *
   * const O = getOrd(ordNumber)
   * assert.strictEqual(O.compare(none, none), 0)
   * assert.strictEqual(O.compare(none, some(1)), -1)
   * assert.strictEqual(O.compare(some(1), none), 1)
   * assert.strictEqual(O.compare(some(1), some(2)), -1)
   * assert.strictEqual(O.compare(some(1), some(1)), 0)
   *
   * @category instances
   * @since 2.0.0
   */
  function getOrd(O) {
      return {
          equals: getEq(O).equals,
          compare: function (x, y) { return (x === y ? 0 : exports.isSome(x) ? (exports.isSome(y) ? O.compare(x.value, y.value) : 1) : -1); }
      };
  }
  exports.getOrd = getOrd;
  /**
   * `Apply` semigroup
   *
   * | x       | y       | concat(x, y)       |
   * | ------- | ------- | ------------------ |
   * | none    | none    | none               |
   * | some(a) | none    | none               |
   * | none    | some(a) | none               |
   * | some(a) | some(b) | some(concat(a, b)) |
   *
   * @example
   * import { getApplySemigroup, some, none } from 'fp-ts/Option'
   * import { semigroupSum } from 'fp-ts/Semigroup'
   *
   * const S = getApplySemigroup(semigroupSum)
   * assert.deepStrictEqual(S.concat(none, none), none)
   * assert.deepStrictEqual(S.concat(some(1), none), none)
   * assert.deepStrictEqual(S.concat(none, some(1)), none)
   * assert.deepStrictEqual(S.concat(some(1), some(2)), some(3))
   *
   * @category instances
   * @since 2.0.0
   */
  function getApplySemigroup(S) {
      return {
          concat: function (x, y) { return (exports.isSome(x) && exports.isSome(y) ? exports.some(S.concat(x.value, y.value)) : exports.none); }
      };
  }
  exports.getApplySemigroup = getApplySemigroup;
  /**
   * @category instances
   * @since 2.0.0
   */
  function getApplyMonoid(M) {
      return {
          concat: getApplySemigroup(M).concat,
          empty: exports.some(M.empty)
      };
  }
  exports.getApplyMonoid = getApplyMonoid;
  /**
   * Monoid returning the left-most non-`None` value
   *
   * | x       | y       | concat(x, y) |
   * | ------- | ------- | ------------ |
   * | none    | none    | none         |
   * | some(a) | none    | some(a)      |
   * | none    | some(a) | some(a)      |
   * | some(a) | some(b) | some(a)      |
   *
   * @example
   * import { getFirstMonoid, some, none } from 'fp-ts/Option'
   *
   * const M = getFirstMonoid<number>()
   * assert.deepStrictEqual(M.concat(none, none), none)
   * assert.deepStrictEqual(M.concat(some(1), none), some(1))
   * assert.deepStrictEqual(M.concat(none, some(1)), some(1))
   * assert.deepStrictEqual(M.concat(some(1), some(2)), some(1))
   *
   * @category instances
   * @since 2.0.0
   */
  function getFirstMonoid() {
      return {
          concat: function (x, y) { return (exports.isNone(x) ? y : x); },
          empty: exports.none
      };
  }
  exports.getFirstMonoid = getFirstMonoid;
  /**
   * Monoid returning the right-most non-`None` value
   *
   * | x       | y       | concat(x, y) |
   * | ------- | ------- | ------------ |
   * | none    | none    | none         |
   * | some(a) | none    | some(a)      |
   * | none    | some(a) | some(a)      |
   * | some(a) | some(b) | some(b)      |
   *
   * @example
   * import { getLastMonoid, some, none } from 'fp-ts/Option'
   *
   * const M = getLastMonoid<number>()
   * assert.deepStrictEqual(M.concat(none, none), none)
   * assert.deepStrictEqual(M.concat(some(1), none), some(1))
   * assert.deepStrictEqual(M.concat(none, some(1)), some(1))
   * assert.deepStrictEqual(M.concat(some(1), some(2)), some(2))
   *
   * @category instances
   * @since 2.0.0
   */
  function getLastMonoid() {
      return {
          concat: function (x, y) { return (exports.isNone(y) ? x : y); },
          empty: exports.none
      };
  }
  exports.getLastMonoid = getLastMonoid;
  /**
   * Monoid returning the left-most non-`None` value. If both operands are `Some`s then the inner values are
   * concatenated using the provided `Semigroup`
   *
   * | x       | y       | concat(x, y)       |
   * | ------- | ------- | ------------------ |
   * | none    | none    | none               |
   * | some(a) | none    | some(a)            |
   * | none    | some(a) | some(a)            |
   * | some(a) | some(b) | some(concat(a, b)) |
   *
   * @example
   * import { getMonoid, some, none } from 'fp-ts/Option'
   * import { semigroupSum } from 'fp-ts/Semigroup'
   *
   * const M = getMonoid(semigroupSum)
   * assert.deepStrictEqual(M.concat(none, none), none)
   * assert.deepStrictEqual(M.concat(some(1), none), some(1))
   * assert.deepStrictEqual(M.concat(none, some(1)), some(1))
   * assert.deepStrictEqual(M.concat(some(1), some(2)), some(3))
   *
   * @category instances
   * @since 2.0.0
   */
  function getMonoid(S) {
      return {
          concat: function (x, y) { return (exports.isNone(x) ? y : exports.isNone(y) ? x : exports.some(S.concat(x.value, y.value))); },
          empty: exports.none
      };
  }
  exports.getMonoid = getMonoid;
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Functor = {
      URI: exports.URI,
      map: map_
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Applicative = {
      URI: exports.URI,
      map: map_,
      ap: ap_,
      of: exports.of
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Monad = {
      URI: exports.URI,
      map: map_,
      ap: ap_,
      of: exports.of,
      chain: chain_
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Foldable = {
      URI: exports.URI,
      reduce: reduce_,
      foldMap: foldMap_,
      reduceRight: reduceRight_
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Alt = {
      URI: exports.URI,
      map: map_,
      alt: alt_
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Alternative = {
      URI: exports.URI,
      map: map_,
      ap: ap_,
      of: exports.of,
      alt: alt_,
      zero: exports.zero
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Extend = {
      URI: exports.URI,
      map: map_,
      extend: extend_
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Compactable = {
      URI: exports.URI,
      compact: exports.compact,
      separate: exports.separate
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Filterable = {
      URI: exports.URI,
      map: map_,
      compact: exports.compact,
      separate: exports.separate,
      filter: filter_,
      filterMap: filterMap_,
      partition: partition_,
      partitionMap: partitionMap_
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Traversable = {
      URI: exports.URI,
      map: map_,
      reduce: reduce_,
      foldMap: foldMap_,
      reduceRight: reduceRight_,
      traverse: traverse_,
      sequence: exports.sequence
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.Witherable = {
      URI: exports.URI,
      map: map_,
      reduce: reduce_,
      foldMap: foldMap_,
      reduceRight: reduceRight_,
      traverse: traverse_,
      sequence: exports.sequence,
      compact: exports.compact,
      separate: exports.separate,
      filter: filter_,
      filterMap: filterMap_,
      partition: partition_,
      partitionMap: partitionMap_,
      wither: wither_,
      wilt: wilt_
  };
  /**
   * @category instances
   * @since 2.7.0
   */
  exports.MonadThrow = {
      URI: exports.URI,
      map: map_,
      ap: ap_,
      of: exports.of,
      chain: chain_,
      throwError: exports.throwError
  };
  // TODO: remove in v3
  /**
   * @category instances
   * @since 2.0.0
   */
  exports.option = {
      URI: exports.URI,
      map: map_,
      of: exports.of,
      ap: ap_,
      chain: chain_,
      reduce: reduce_,
      foldMap: foldMap_,
      reduceRight: reduceRight_,
      traverse: traverse_,
      sequence: exports.sequence,
      zero: exports.zero,
      alt: alt_,
      extend: extend_,
      compact: exports.compact,
      separate: exports.separate,
      filter: filter_,
      filterMap: filterMap_,
      partition: partition_,
      partitionMap: partitionMap_,
      wither: wither_,
      wilt: wilt_,
      throwError: exports.throwError
  };
  // -------------------------------------------------------------------------------------
  // utils
  // -------------------------------------------------------------------------------------
  /**
   * Returns `true` if `ma` contains `a`
   *
   * @example
   * import { some, none, elem } from 'fp-ts/Option'
   * import { eqNumber } from 'fp-ts/Eq'
   *
   * assert.strictEqual(elem(eqNumber)(1, some(1)), true)
   * assert.strictEqual(elem(eqNumber)(2, some(1)), false)
   * assert.strictEqual(elem(eqNumber)(1, none), false)
   *
   * @since 2.0.0
   */
  function elem(E) {
      return function (a, ma) { return (exports.isNone(ma) ? false : E.equals(a, ma.value)); };
  }
  exports.elem = elem;
  /**
   * Returns `true` if the predicate is satisfied by the wrapped value
   *
   * @example
   * import { some, none, exists } from 'fp-ts/Option'
   * import { pipe } from 'fp-ts/function'
   *
   * assert.strictEqual(
   *   pipe(
   *     some(1),
   *     exists(n => n > 0)
   *   ),
   *   true
   * )
   * assert.strictEqual(
   *   pipe(
   *     some(1),
   *     exists(n => n > 1)
   *   ),
   *   false
   * )
   * assert.strictEqual(
   *   pipe(
   *     none,
   *     exists(n => n > 0)
   *   ),
   *   false
   * )
   *
   * @since 2.0.0
   */
  function exists(predicate) {
      return function (ma) { return (exports.isNone(ma) ? false : predicate(ma.value)); };
  }
  exports.exists = exists;
  /**
   * Returns a `Refinement` (i.e. a custom type guard) from a `Option` returning function.
   * This function ensures that a custom type guard definition is type-safe.
   *
   * ```ts
   * import { some, none, getRefinement } from 'fp-ts/Option'
   *
   * type A = { type: 'A' }
   * type B = { type: 'B' }
   * type C = A | B
   *
   * const isA = (c: C): c is A => c.type === 'B' // <= typo but typescript doesn't complain
   * const isA = getRefinement<C, A>(c => (c.type === 'B' ? some(c) : none)) // static error: Type '"B"' is not assignable to type '"A"'
   * ```
   *
   * @since 2.0.0
   */
  function getRefinement(getOption) {
      return function (a) { return exports.isSome(getOption(a)); };
  }
  exports.getRefinement = getRefinement;
  // -------------------------------------------------------------------------------------
  // do notation
  // -------------------------------------------------------------------------------------
  /**
   * @since 2.8.0
   */
  exports.bindTo = function (name) { return exports.map(function_1.bindTo_(name)); };
  /**
   * @since 2.8.0
   */
  exports.bind = function (name, f) {
      return exports.chain(function (a) {
          return function_1.pipe(f(a), exports.map(function (b) { return function_1.bind_(a, name, b); }));
      });
  };
  // -------------------------------------------------------------------------------------
  // pipeable sequence S
  // -------------------------------------------------------------------------------------
  /**
   * @since 2.8.0
   */
  exports.apS = function (name, fb) {
      return function_1.flow(exports.map(function (a) { return function (b) { return function_1.bind_(a, name, b); }; }), exports.ap(fb));
  };
  