"use strict"
var __createBinding =
  (this && this.__createBinding) ||
  (Object.create
    ? function (o, m, k, k2) {
        if (k2 === undefined) k2 = k
        Object.defineProperty(o, k2, {
          enumerable: true,
          get: function () {
            return m[k]
          }
        })
      }
    : function (o, m, k, k2) {
        if (k2 === undefined) k2 = k
        o[k2] = m[k]
      })
var __setModuleDefault =
  (this && this.__setModuleDefault) ||
  (Object.create
    ? function (o, v) {
        Object.defineProperty(o, "default", { enumerable: true, value: v })
      }
    : function (o, v) {
        o["default"] = v
      })
var __importStar =
  (this && this.__importStar) ||
  function (mod) {
    if (mod && mod.__esModule) return mod
    var result = {}
    if (mod != null)
      for (var k in mod)
        if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
          __createBinding(result, mod, k)
    __setModuleDefault(result, mod)
    return result
  }
Object.defineProperty(exports, "__esModule", { value: true })
exports.replaceService_ =
  exports.replaceService =
  exports.replaceServiceM_ =
  exports.replaceServiceM =
  exports.provideService_ =
  exports.provideService =
  exports.provideServiceM_ =
  exports.provideServiceM =
  exports.services =
  exports.service =
  exports.accessService =
  exports.accessServiceM =
  exports.accessServices =
  exports.accessServicesT =
  exports.accessServicesTM =
  exports.accessServicesM =
    void 0
// tracing: off
/**
 * Copyright 2020 Michael Arnaldi and the Matechs Garage Contributors.
 */
const A = __importStar(require("../Collections/Immutable/Array"))
const R = __importStar(require("../Collections/Immutable/Dictionary"))
const core = __importStar(require("../Effect/core"))
const Has_1 = require("../Has")
const Tracing_1 = require("../Tracing")
/**
 * Access a record of services with the required Service Entries
 */
function accessServicesM(s) {
  return (f, __trace) => core.accessM((r) => f(R.map_(s, (v) => r[v.key])), __trace)
}
exports.accessServicesM = accessServicesM
/**
 * Access a tuple of services with the required Service Entries monadically
 */
function accessServicesTM(...s) {
  return (f, __trace) => core.accessM((r) => f(...A.map_(s, (v) => r[v.key])), __trace)
}
exports.accessServicesTM = accessServicesTM
/**
 * Access a tuple of services with the required Service Entries
 */
function accessServicesT(...s) {
  return (f, __trace) => core.access((r) => f(...A.map_(s, (v) => r[v.key])), __trace)
}
exports.accessServicesT = accessServicesT
/**
 * Access a record of services with the required Service Entries
 */
function accessServices(s) {
  return (f, __trace) => core.access((r) => f(R.map_(s, (v) => r[v.key])), __trace)
}
exports.accessServices = accessServices
/**
 * Access a service with the required Service Entry
 */
function accessServiceM(s) {
  return (f, __trace) => core.accessM((r) => f(r[s.key]), __trace)
}
exports.accessServiceM = accessServiceM
/**
 * Access a service with the required Service Entry
 */
function accessService(s) {
  return (f, __trace) => accessServiceM(s)((a) => core.succeed(f(a)), __trace)
}
exports.accessService = accessService
/**
 * Accesses the specified service in the environment of the effect.
 */
function service(s, __trace) {
  return accessServiceM(s)(core.succeed, __trace)
}
exports.service = service
/**
 * Accesses the specified services in the environment of the effect.
 *
 * @trace call
 */
function services(...s) {
  return core.access(
    (r) => s.map((tag) => tag.read(r)),
    (0, Tracing_1.accessCallTrace)()
  )
}
exports.services = services
/**
 * Provides the service with the required Service Entry
 */
function provideServiceM(_) {
  return (service, __trace) => (ma) =>
    core.accessM((r) =>
      core.chain_(service, (t) =>
        core.provideAll_(ma, (0, Has_1.mergeEnvironments)(_, r, t), __trace)
      )
    )
}
exports.provideServiceM = provideServiceM
/**
 * Provides the service with the required Service Entry
 */
function provideServiceM_(ma, _, service, __trace) {
  return core.accessM((r) =>
    core.chain_(service, (t) =>
      core.provideAll_(ma, (0, Has_1.mergeEnvironments)(_, r, t), __trace)
    )
  )
}
exports.provideServiceM_ = provideServiceM_
/**
 * Provides the service with the required Service Entry
 */
function provideService(_) {
  return (service, __trace) => (ma) =>
    provideServiceM(_)(core.succeed(service), __trace)(ma)
}
exports.provideService = provideService
/**
 * Provides the service with the required Service Entry
 */
function provideService_(ma, _, service, __trace) {
  return provideServiceM(_)(core.succeed(service), __trace)(ma)
}
exports.provideService_ = provideService_
/**
 * Replaces the service with the required Service Entry
 */
function replaceServiceM(_, f, __trace) {
  return (ma) => accessServiceM(_)((t) => provideServiceM(_)(f(t), __trace)(ma))
}
exports.replaceServiceM = replaceServiceM
/**
 * Replaces the service with the required Service Entry
 */
function replaceServiceM_(ma, _, f, __trace) {
  return accessServiceM(_)((t) => provideServiceM(_)(f(t), __trace)(ma))
}
exports.replaceServiceM_ = replaceServiceM_
/**
 * Replaces the service with the required Service Entry
 *
 * @dataFirst replaceService_
 */
function replaceService(_, f, __trace) {
  return (ma) => replaceService_(ma, _, f, __trace)
}
exports.replaceService = replaceService
/**
 * Replaces the service with the required Service Entry
 *
 * @trace 2
 */
function replaceService_(ma, _, f, __trace) {
  return accessServiceM(_)((t) =>
    provideServiceM(_)(
      core.succeedWith(() => f(t)),
      __trace
    )(ma)
  )
}
exports.replaceService_ = replaceService_
//# sourceMappingURL=has.js.map
