"use strict"
// tracing: off
Object.defineProperty(exports, "__esModule", { value: true })
exports.gen = exports.GenSync = void 0
/**
 * inspired by https://github.com/tusharmath/qio/pull/22 (revised)
 */
const commons_1 = require("../Effect/commons")
const Function_1 = require("../Function")
const GlobalExceptions_1 = require("../GlobalExceptions")
const Utils_1 = require("../Utils")
const core_1 = require("./core")
const has_1 = require("./has")
class GenSync {
  constructor(effect) {
    this.effect = effect
  }
  *[Symbol.iterator]() {
    return yield this
  }
}
exports.GenSync = GenSync
const adapter = (_, __) => {
  if (Utils_1.isTag(_)) {
    return new GenSync(has_1.accessService(_)(Function_1.identity))
  }
  if (Utils_1.isEither(_)) {
    return new GenSync(
      _._tag === "Left" ? core_1.fail(_.left) : core_1.succeed(_.right)
    )
  }
  if (Utils_1.isOption(_)) {
    return new GenSync(
      _._tag === "None"
        ? core_1.fail(__ ? __() : new GlobalExceptions_1.NoSuchElementException())
        : core_1.succeed(_.value)
    )
  }
  return new GenSync(_)
}
function gen(f) {
  return core_1.suspend(() => {
    const iterator = f(adapter)
    const state = iterator.next()
    function run(state) {
      if (state.done) {
        return core_1.succeed(state.value)
      }
      return core_1.chain_(state.value["effect"], (val) => {
        const next = iterator.next(val)
        return run(next)
      })
    }
    return run(state)
  })
}
exports.gen = gen
//# sourceMappingURL=gen.js.map
