// Generated by purs version 0.14.5
"use strict";
var Control_Applicative = require("../Control.Applicative/index.js");
var Control_Apply = require("../Control.Apply/index.js");
var Control_Bind = require("../Control.Bind/index.js");
var Data_Array = require("../Data.Array/index.js");
var Data_Foldable = require("../Data.Foldable/index.js");
var Data_Functor = require("../Data.Functor/index.js");
var Data_Maybe = require("../Data.Maybe/index.js");
var Data_Monoid = require("../Data.Monoid/index.js");
var Data_Semigroup = require("../Data.Semigroup/index.js");
var Data_Unit = require("../Data.Unit/index.js");
var Effect = require("../Effect/index.js");
var Effect_Ref = require("../Effect.Ref/index.js");
var Effect_Unsafe = require("../Effect.Unsafe/index.js");
var Safe_Coerce = require("../Safe.Coerce/index.js");
var Unsafe_Reference = require("../Unsafe.Reference/index.js");
var Subscription = function (x) {
    return x;
};
var Listener = function (x) {
    return x;
};
var Emitter = function (x) {
    return x;
};
var unsubscribe = function (v) {
    return v;
};
var subscribe = function (v) {
    return function (k) {
        return v((function () {
            var $55 = Data_Functor["void"](Effect.functorEffect);
            return function ($56) {
                return $55(k($56));
            };
        })());
    };
};
var semigroupSubscription = Effect.semigroupEffect(Data_Semigroup.semigroupUnit);
var notify = function (v) {
    return function (a) {
        return v(a);
    };
};
var monoidSubscription = Effect.monoidEffect(Data_Monoid.monoidUnit);
var makeEmitter = Safe_Coerce.coerce();
var functorEmitter = {
    map: function (f) {
        return function (v) {
            return function (k) {
                return v(function ($57) {
                    return k(f($57));
                });
            };
        };
    }
};
var fold = function (f) {
    return function (v) {
        return function (b) {
            return function (k) {
                return function __do() {
                    var result = Effect_Ref["new"](b)();
                    return v(function (a) {
                        return Control_Bind.bind(Effect.bindEffect)(Effect_Ref.modify(f(a))(result))(k);
                    })();
                };
            };
        };
    };
};
var filter = function (p) {
    return function (v) {
        return function (k) {
            return v(function (a) {
                var $36 = p(a);
                if ($36) {
                    return k(a);
                };
                return Control_Applicative.pure(Effect.applicativeEffect)(Data_Unit.unit);
            });
        };
    };
};
var create = function __do() {
    var subscribers = Effect_Ref["new"]([  ])();
    return {
        emitter: function (k) {
            return function __do() {
                Effect_Ref.modify_(function (v) {
                    return Data_Semigroup.append(Data_Semigroup.semigroupArray)(v)([ k ]);
                })(subscribers)();
                return Effect_Ref.modify_(Data_Array.deleteBy(Unsafe_Reference.unsafeRefEq)(k))(subscribers);
            };
        },
        listener: function (a) {
            return Control_Bind.bind(Effect.bindEffect)(Effect_Ref.read(subscribers))(Data_Foldable.traverse_(Effect.applicativeEffect)(Data_Foldable.foldableArray)(function (k) {
                return k(a);
            }));
        }
    };
};
var fix = function (f) {
    var v = Effect_Unsafe.unsafePerformEffect(create);
    var v1 = f(v.emitter);
    return function (k) {
        return function __do() {
            var v2 = subscribe(v1.input)(notify(v.listener))();
            var v3 = subscribe(v1.output)(k)();
            return Control_Apply.applySecond(Effect.applyEffect)(v2)(v3);
        };
    };
};
var contravariantListener = {
    cmap: function (f) {
        return function (v) {
            return Safe_Coerce.coerce()(function ($58) {
                return v(f($58));
            });
        };
    }
};
var applyEmitter = {
    apply: function (v) {
        return function (v1) {
            return function (k) {
                return function __do() {
                    var latestA = Effect_Ref["new"](Data_Maybe.Nothing.value)();
                    var latestB = Effect_Ref["new"](Data_Maybe.Nothing.value)();
                    var v2 = v(function (a) {
                        return function __do() {
                            Effect_Ref.write(new Data_Maybe.Just(a))(latestA)();
                            return Control_Bind.bind(Effect.bindEffect)(Effect_Ref.read(latestB))(Data_Foldable.traverse_(Effect.applicativeEffect)(Data_Foldable.foldableMaybe)(function ($59) {
                                return k(a($59));
                            }))();
                        };
                    })();
                    var v3 = v1(function (b) {
                        return function __do() {
                            Effect_Ref.write(new Data_Maybe.Just(b))(latestB)();
                            return Control_Bind.bind(Effect.bindEffect)(Effect_Ref.read(latestA))(Data_Foldable.traverse_(Effect.applicativeEffect)(Data_Foldable.foldableMaybe)(function ($60) {
                                return k((function (v3) {
                                    return v3(b);
                                })($60));
                            }))();
                        };
                    })();
                    return Control_Apply.applySecond(Effect.applyEffect)(v2)(v3);
                };
            };
        };
    },
    Functor0: function () {
        return functorEmitter;
    }
};
var semigroupEmitter = function (dictSemigroup) {
    return {
        append: Control_Apply.lift2(applyEmitter)(Data_Semigroup.append(dictSemigroup))
    };
};
var monoidEmitter = function (dictMonoid) {
    return {
        mempty: Data_Monoid.mempty(Data_Monoid.monoidFn(Effect.monoidEffect(monoidSubscription))),
        Semigroup0: function () {
            return semigroupEmitter(dictMonoid.Semigroup0());
        }
    };
};
var applicativeEmitter = {
    pure: function (a) {
        return function (k) {
            return function __do() {
                k(a)();
                return Control_Applicative.pure(Effect.applicativeEffect)(Data_Unit.unit);
            };
        };
    },
    Apply0: function () {
        return applyEmitter;
    }
};
var altEmitter = {
    alt: function (v) {
        return function (v1) {
            return function (k) {
                return function __do() {
                    var v2 = v(k)();
                    var v3 = v1(k)();
                    return Control_Apply.applySecond(Effect.applyEffect)(v2)(v3);
                };
            };
        };
    },
    Functor0: function () {
        return functorEmitter;
    }
};
var plusEmitter = {
    empty: function (v) {
        return Control_Applicative.pure(Effect.applicativeEffect)(Control_Applicative.pure(Effect.applicativeEffect)(Data_Unit.unit));
    },
    Alt0: function () {
        return altEmitter;
    }
};
var alternativeEmitter = {
    Applicative0: function () {
        return applicativeEmitter;
    },
    Plus1: function () {
        return plusEmitter;
    }
};
module.exports = {
    create: create,
    notify: notify,
    makeEmitter: makeEmitter,
    subscribe: subscribe,
    unsubscribe: unsubscribe,
    fold: fold,
    filter: filter,
    fix: fix,
    functorEmitter: functorEmitter,
    applyEmitter: applyEmitter,
    applicativeEmitter: applicativeEmitter,
    altEmitter: altEmitter,
    plusEmitter: plusEmitter,
    alternativeEmitter: alternativeEmitter,
    semigroupEmitter: semigroupEmitter,
    monoidEmitter: monoidEmitter,
    contravariantListener: contravariantListener,
    semigroupSubscription: semigroupSubscription,
    monoidSubscription: monoidSubscription
};
