text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  var Apply_1 = require("./Apply");
  var Monoid_1 = require("./Monoid");
  var Option_1 = require("./Option");
  var Ord_1 = require("./Ord");
  /**
   * @function
   * @since 1.0.0
   */
  function getFoldableComposition(F, G) {
      return {
          reduce: function (fga, b, f) { return F.reduce(fga, b, function (b, ga) { return G.reduce(ga, b, f); }); }
      };
  }
  exports.getFoldableComposition = getFoldableComposition;
  /**
   * A default implementation of `foldMap` using `foldl`
   * @function
   * @since 1.0.0
   */
  function foldMap(F, M) {
      return function (fa, f) { return F.reduce(fa, M.empty, function (acc, x) { return M.concat(acc, f(x)); }); };
  }
  exports.foldMap = foldMap;
  /**
   * A default implementation of `foldr` using `foldMap`
   * @function
   * @since 1.0.0
   */
  function foldr(F) {
      var toArrayF = toArray(F);
      return function (fa, b, f) { return toArrayF(fa).reduceRight(function (acc, a) { return f(a, acc); }, b); };
  }
  exports.foldr = foldr;
  /**
   * @function
   * @since 1.0.0
   */
  function fold(F, M) {
      return function (fa) { return F.reduce(fa, M.empty, M.concat); };
  }
  exports.fold = fold;
  /**
   * Similar to 'reduce', but the result is encapsulated in a monad.
   *
   * Note: this function is not generally stack-safe, e.g., for monads which build up thunks a la `IO`.
   * @function
   * @since 1.0.0
   */
  function foldM(F, M) {
      return function (f, b, fa) { return F.reduce(fa, M.of(b), function (mb, a) { return M.chain(mb, function (b) { return f(b, a); }); }); };
  }
  exports.foldM = foldM;
  /**
   * Use {@link traverse}
   * @function
   * @since 1.0.0
   * @deprecated
   */
  function traverse_(M, F) {
      var toArrayF = toArray(F);
      var applyFirstM = Apply_1.applyFirst(M);
      var initialValue = M.of(undefined);
      return function (f, fa) { return toArrayF(fa).reduce(function (mu, a) { return applyFirstM(mu, f(a)); }, initialValue); };
  }
  exports.traverse_ = traverse_;
  /**
   * Perform all of the effects in some data structure in the order given by the `Foldable` instance, ignoring the final result.
   * @function
   * @since 1.0.0
   */
  function sequence_(M, F) {
      var traverse_MF = traverse_(M, F);
      return function (fa) { return traverse_MF(function (ma) { return ma; }, fa); };
  }
  exports.sequence_ = sequence_;
  /**
   * Combines a collection of elements using the `Alt` operation
   * @function
   * @since 1.0.0
   */
  function oneOf(F, P) {
      return function (fga) { return F.reduce(fga, P.zero(), function (acc, a) { return P.alt(acc, a); }); };
  }
  exports.oneOf = oneOf;
  /**
   * Fold a data structure, accumulating values in some `Monoid`, combining adjacent elements using the specified separator
   * @function
   * @since 1.0.0
   */
  function intercalate(F, M) {
      return function (sep) {
          function go(_a, x) {
              var init = _a.init, acc = _a.acc;
              return init ? { init: false, acc: x } : { init: false, acc: M.concat(M.concat(acc, sep), x) };
          }
          return function (fm) { return F.reduce(fm, { init: true, acc: M.empty }, go).acc; };
      };
  }
  exports.intercalate = intercalate;
  /**
   * Find the sum of the numeric values in a data structure
   * @function
   * @since 1.0.0
   */
  function sum(F, S) {
      return function (fa) { return F.reduce(fa, S.zero, function (b, a) { return S.add(b, a); }); };
  }
  exports.sum = sum;
  /**
   * Find the product of the numeric values in a data structure
   * @function
   * @since 1.0.0
   */
  function product(F, S) {
      return function (fa) { return F.reduce(fa, S.one, function (b, a) { return S.mul(b, a); }); };
  }
  exports.product = product;
  /**
   * Test whether a value is an element of a data structure
   * @function
   * @since 1.0.0
   */
  function elem(F, S) {
      return function (a, fa) { return F.reduce(fa, false, function (b, x) { return b || S.equals(x, a); }); };
  }
  exports.elem = elem;
  /**
   * Try to find an element in a data structure which satisfies a predicate
   * @function
   * @since 1.0.0
   */
  function find(F) {
      return function (fa, p) {
          return F.reduce(fa, Option_1.none, function (b, a) {
              if (b.isNone() && p(a)) {
                  return Option_1.some(a);
              }
              else {
                  return b;
              }
          });
      };
  }
  exports.find = find;
  /**
   * Find the smallest element of a structure, according to its `Ord` instance
   * @function
   * @since 1.0.0
   */
  function minimum(F, O) {
      var minO = Ord_1.min(O);
      return function (fa) { return F.reduce(fa, Option_1.none, function (b, a) { return (b.isNone() ? Option_1.some(a) : Option_1.some(minO(b.value, a))); }); };
  }
  exports.minimum = minimum;
  /**
   * Find the largest element of a structure, according to its `Ord` instance
   * @function
   * @since 1.0.0
   */
  function maximum(F, O) {
      var maxO = Ord_1.max(O);
      return function (fa) { return F.reduce(fa, Option_1.none, function (b, a) { return (b.isNone() ? Option_1.some(a) : Option_1.some(maxO(b.value, a))); }); };
  }
  exports.maximum = maximum;
  /**
   * @function
   * @since 1.0.0
   */
  function toArray(F) {
      var foldMapF = foldMap(F, Monoid_1.unsafeMonoidArray);
      return function (fa) { return foldMapF(fa, function (a) { return [a]; }); };
  }
  exports.toArray = toArray;
  /**
   * Traverse a data structure, performing some effects encoded by an `Applicative` functor at each value, ignoring the
   * final result.
   * @function
   * @since 1.7.0
   */
  function traverse(M, F) {
      var traverseMF = traverse_(M, F);
      return function (fa, f) { return traverseMF(f, fa); };
  }
  exports.traverse = traverse;
  //# sourceMappingURL=Foldable.js.map