"use strict";Object.defineProperty(exports, "__esModule", {value: true});

var _chunkOTKMOSH2js = require('./chunk-OTKMOSH2.js');


var _chunkSQA7G4TEjs = require('./chunk-SQA7G4TE.js');


var _chunk6C3VEZWHjs = require('./chunk-6C3VEZWH.js');

// src/Apply.ts
var Apply_exports = {};
_chunk6C3VEZWHjs.__export.call(void 0, Apply_exports, {
  ap: () => ap,
  apFirst: () => apFirst,
  apS: () => apS,
  apSecond: () => apSecond,
  getApplySemigroup: () => getApplySemigroup,
  sequenceS: () => sequenceS,
  sequenceT: () => sequenceT
});
function ap(F, G) {
  return (fa) => (fab) => F.ap(
    F.map(fab, (gab) => (ga) => G.ap(gab, ga)),
    fa
  );
}
function apFirst(A) {
  return (second) => (first) => A.ap(
    A.map(first, (a) => () => a),
    second
  );
}
function apSecond(A) {
  return (second) => (first) => A.ap(
    A.map(first, () => (b) => b),
    second
  );
}
function apS(F) {
  return (name, fb) => (fa) => F.ap(
    F.map(fa, (a) => (b) => Object.assign({}, a, { [name]: b })),
    fb
  );
}
function getApplySemigroup(F) {
  return (S) => ({
    concat: (first, second) => F.ap(
      F.map(first, (x) => (y) => S.concat(x, y)),
      second
    )
  });
}
function curried(f, n, acc) {
  return function(x) {
    const combined = Array(acc.length + 1);
    for (let i = 0; i < acc.length; i++) {
      combined[i] = acc[i];
    }
    combined[acc.length] = x;
    return n === 0 ? f.apply(null, combined) : curried(f, n - 1, combined);
  };
}
var tupleConstructors = {
  1: (a) => [a],
  2: (a) => (b) => [a, b],
  3: (a) => (b) => (c) => [a, b, c],
  4: (a) => (b) => (c) => (d) => [a, b, c, d],
  5: (a) => (b) => (c) => (d) => (e) => [a, b, c, d, e]
};
function getTupleConstructor(len) {
  if (!_chunkOTKMOSH2js.has.call(tupleConstructors, len)) {
    tupleConstructors[len] = curried(_chunkSQA7G4TEjs.tuple, len - 1, []);
  }
  return tupleConstructors[len];
}
function sequenceT(F) {
  return (...args) => {
    const len = args.length;
    const f = getTupleConstructor(len);
    let fas = F.map(args[0], f);
    for (let i = 1; i < len; i++) {
      fas = F.ap(fas, args[i]);
    }
    return fas;
  };
}
function getRecordConstructor(keys) {
  const len = keys.length;
  switch (len) {
    case 1:
      return (a) => ({ [keys[0]]: a });
    case 2:
      return (a) => (b) => ({ [keys[0]]: a, [keys[1]]: b });
    case 3:
      return (a) => (b) => (c) => ({ [keys[0]]: a, [keys[1]]: b, [keys[2]]: c });
    case 4:
      return (a) => (b) => (c) => (d) => ({
        [keys[0]]: a,
        [keys[1]]: b,
        [keys[2]]: c,
        [keys[3]]: d
      });
    case 5:
      return (a) => (b) => (c) => (d) => (e) => ({
        [keys[0]]: a,
        [keys[1]]: b,
        [keys[2]]: c,
        [keys[3]]: d,
        [keys[4]]: e
      });
    default:
      return curried(
        (...args) => {
          const r = {};
          for (let i = 0; i < len; i++) {
            r[keys[i]] = args[i];
          }
          return r;
        },
        len - 1,
        []
      );
  }
}
function sequenceS(F) {
  return (r) => {
    const keys = Object.keys(r);
    const len = keys.length;
    const f = getRecordConstructor(keys);
    let fr = F.map(r[keys[0]], f);
    for (let i = 1; i < len; i++) {
      fr = F.ap(fr, r[keys[i]]);
    }
    return fr;
  };
}










exports.ap = ap; exports.apFirst = apFirst; exports.apSecond = apSecond; exports.apS = apS; exports.getApplySemigroup = getApplySemigroup; exports.sequenceT = sequenceT; exports.sequenceS = sequenceS; exports.Apply_exports = Apply_exports;
