// ets_tracing: off

/**
 * inspired by https://github.com/tusharmath/qio/pull/22 (revised)
 */
import { _A, _E, _R } from "../Effect/commons";
import { identity } from "../Function";
import { NoSuchElementException } from "../GlobalExceptions";
import { isEither, isOption, isTag } from "../Utils";
import { chain_, fail, succeed, suspend } from "./core";
import { accessService } from "./has";
export class GenSync {
  constructor(effect) {
    this.effect = effect;
  }

  *[Symbol.iterator]() {
    return yield this;
  }

}

const adapter = (_, __) => {
  if (isTag(_)) {
    return new GenSync(accessService(_)(identity));
  }

  if (isEither(_)) {
    return new GenSync(_._tag === "Left" ? fail(_.left) : succeed(_.right));
  }

  if (isOption(_)) {
    return new GenSync(_._tag === "None" ? fail(__ ? __() : new NoSuchElementException()) : succeed(_.value));
  }

  return new GenSync(_);
};

export function gen(f) {
  return suspend(() => {
    const iterator = f(adapter);
    const state = iterator.next();

    function run(state) {
      if (state.done) {
        return succeed(state.value);
      }

      return chain_(state.value["effect"], val => {
        const next = iterator.next(val);
        return run(next);
      });
    }

    return run(state);
  });
}
//# sourceMappingURL=gen.js.map