// Generated by purs version 0.14.5
"use strict";
var $foreign = require("./foreign.js");
var Control_Alternative = require("../Control.Alternative/index.js");
var Control_Apply = require("../Control.Apply/index.js");
var Control_Bind = require("../Control.Bind/index.js");
var Data_Boolean = require("../Data.Boolean/index.js");
var Data_Bounded = require("../Data.Bounded/index.js");
var Data_Either = require("../Data.Either/index.js");
var Data_Eq = require("../Data.Eq/index.js");
var Data_Function = require("../Data.Function/index.js");
var Data_Functor = require("../Data.Functor/index.js");
var Data_Maybe = require("../Data.Maybe/index.js");
var Data_Ord = require("../Data.Ord/index.js");
var Data_Ordering = require("../Data.Ordering/index.js");
var Data_Show = require("../Data.Show/index.js");
var Data_Tuple = require("../Data.Tuple/index.js");
var Data_Unfoldable = require("../Data.Unfoldable/index.js");
var Data_Unfoldable1 = require("../Data.Unfoldable1/index.js");
var Data_Unit = require("../Data.Unit/index.js");
var Cardinality = function (x) {
    return x;
};
var toEnum = function (dict) {
    return dict.toEnum;
};
var succ = function (dict) {
    return dict.succ;
};
var upFromIncluding = function (dictEnum) {
    return function (dictUnfoldable1) {
        return Data_Unfoldable1.unfoldr1(dictUnfoldable1)(Control_Apply.apply(Control_Apply.applyFn)(Data_Tuple.Tuple.create)(succ(dictEnum)));
    };
};
var showCardinality = {
    show: function (v) {
        return "(Cardinality " + (Data_Show.show(Data_Show.showInt)(v) + ")");
    }
};
var pred = function (dict) {
    return dict.pred;
};
var ordCardinality = Data_Ord.ordInt;
var newtypeCardinality = {
    Coercible0: function () {
        return undefined;
    }
};
var fromEnum = function (dict) {
    return dict.fromEnum;
};
var toEnumWithDefaults = function (dictBoundedEnum) {
    return function (low) {
        return function (high) {
            return function (x) {
                var v = toEnum(dictBoundedEnum)(x);
                if (v instanceof Data_Maybe.Just) {
                    return v.value0;
                };
                if (v instanceof Data_Maybe.Nothing) {
                    var $55 = x < fromEnum(dictBoundedEnum)(Data_Bounded.bottom(dictBoundedEnum.Bounded0()));
                    if ($55) {
                        return low;
                    };
                    return high;
                };
                throw new Error("Failed pattern match at Data.Enum (line 158, column 33 - line 160, column 62): " + [ v.constructor.name ]);
            };
        };
    };
};
var eqCardinality = Data_Eq.eqInt;
var enumUnit = {
    succ: Data_Function["const"](Data_Maybe.Nothing.value),
    pred: Data_Function["const"](Data_Maybe.Nothing.value),
    Ord0: function () {
        return Data_Ord.ordUnit;
    }
};
var enumTuple = function (dictEnum) {
    return function (dictBoundedEnum) {
        return {
            succ: function (v) {
                return Data_Maybe.maybe(Data_Functor.map(Data_Maybe.functorMaybe)(Data_Function.flip(Data_Tuple.Tuple.create)(Data_Bounded.bottom(dictBoundedEnum.Bounded0())))(succ(dictEnum)(v.value0)))((function () {
                    var $98 = Data_Tuple.Tuple.create(v.value0);
                    return function ($99) {
                        return Data_Maybe.Just.create($98($99));
                    };
                })())(succ(dictBoundedEnum.Enum1())(v.value1));
            },
            pred: function (v) {
                return Data_Maybe.maybe(Data_Functor.map(Data_Maybe.functorMaybe)(Data_Function.flip(Data_Tuple.Tuple.create)(Data_Bounded.top(dictBoundedEnum.Bounded0())))(pred(dictEnum)(v.value0)))((function () {
                    var $100 = Data_Tuple.Tuple.create(v.value0);
                    return function ($101) {
                        return Data_Maybe.Just.create($100($101));
                    };
                })())(pred(dictBoundedEnum.Enum1())(v.value1));
            },
            Ord0: function () {
                return Data_Tuple.ordTuple(dictEnum.Ord0())((dictBoundedEnum.Enum1()).Ord0());
            }
        };
    };
};
var enumOrdering = {
    succ: function (v) {
        if (v instanceof Data_Ordering.LT) {
            return new Data_Maybe.Just(Data_Ordering.EQ.value);
        };
        if (v instanceof Data_Ordering.EQ) {
            return new Data_Maybe.Just(Data_Ordering.GT.value);
        };
        if (v instanceof Data_Ordering.GT) {
            return Data_Maybe.Nothing.value;
        };
        throw new Error("Failed pattern match at Data.Enum (line 72, column 1 - line 78, column 20): " + [ v.constructor.name ]);
    },
    pred: function (v) {
        if (v instanceof Data_Ordering.LT) {
            return Data_Maybe.Nothing.value;
        };
        if (v instanceof Data_Ordering.EQ) {
            return new Data_Maybe.Just(Data_Ordering.LT.value);
        };
        if (v instanceof Data_Ordering.GT) {
            return new Data_Maybe.Just(Data_Ordering.EQ.value);
        };
        throw new Error("Failed pattern match at Data.Enum (line 72, column 1 - line 78, column 20): " + [ v.constructor.name ]);
    },
    Ord0: function () {
        return Data_Ord.ordOrdering;
    }
};
var enumMaybe = function (dictBoundedEnum) {
    return {
        succ: function (v) {
            if (v instanceof Data_Maybe.Nothing) {
                return new Data_Maybe.Just(new Data_Maybe.Just(Data_Bounded.bottom(dictBoundedEnum.Bounded0())));
            };
            if (v instanceof Data_Maybe.Just) {
                return Data_Functor.map(Data_Maybe.functorMaybe)(Data_Maybe.Just.create)(succ(dictBoundedEnum.Enum1())(v.value0));
            };
            throw new Error("Failed pattern match at Data.Enum (line 80, column 1 - line 84, column 32): " + [ v.constructor.name ]);
        },
        pred: function (v) {
            if (v instanceof Data_Maybe.Nothing) {
                return Data_Maybe.Nothing.value;
            };
            if (v instanceof Data_Maybe.Just) {
                return new Data_Maybe.Just(pred(dictBoundedEnum.Enum1())(v.value0));
            };
            throw new Error("Failed pattern match at Data.Enum (line 80, column 1 - line 84, column 32): " + [ v.constructor.name ]);
        },
        Ord0: function () {
            return Data_Maybe.ordMaybe((dictBoundedEnum.Enum1()).Ord0());
        }
    };
};
var enumInt = {
    succ: function (n) {
        var $68 = n < Data_Bounded.top(Data_Bounded.boundedInt);
        if ($68) {
            return new Data_Maybe.Just(n + 1 | 0);
        };
        return Data_Maybe.Nothing.value;
    },
    pred: function (n) {
        var $69 = n > Data_Bounded.bottom(Data_Bounded.boundedInt);
        if ($69) {
            return new Data_Maybe.Just(n - 1 | 0);
        };
        return Data_Maybe.Nothing.value;
    },
    Ord0: function () {
        return Data_Ord.ordInt;
    }
};
var enumFromTo = function (dictEnum) {
    return function (dictUnfoldable1) {
        var go = function (step) {
            return function (op) {
                return function (to) {
                    return function (a) {
                        return new Data_Tuple.Tuple(a, Control_Bind.bind(Data_Maybe.bindMaybe)(step(a))(function (a$prime) {
                            return Data_Functor.voidLeft(Data_Maybe.functorMaybe)(Control_Alternative.guard(Data_Maybe.alternativeMaybe)(op(a$prime)(to)))(a$prime);
                        }));
                    };
                };
            };
        };
        return function (v) {
            return function (v1) {
                if (Data_Eq.eq((dictEnum.Ord0()).Eq0())(v)(v1)) {
                    return Data_Unfoldable1.singleton(dictUnfoldable1)(v);
                };
                if (Data_Ord.lessThan(dictEnum.Ord0())(v)(v1)) {
                    return Data_Unfoldable1.unfoldr1(dictUnfoldable1)(go(succ(dictEnum))(Data_Ord.lessThanOrEq(dictEnum.Ord0()))(v1))(v);
                };
                if (Data_Boolean.otherwise) {
                    return Data_Unfoldable1.unfoldr1(dictUnfoldable1)(go(pred(dictEnum))(Data_Ord.greaterThanOrEq(dictEnum.Ord0()))(v1))(v);
                };
                throw new Error("Failed pattern match at Data.Enum (line 186, column 14 - line 190, column 51): " + [ v.constructor.name, v1.constructor.name ]);
            };
        };
    };
};
var enumFromThenTo = function (dictUnfoldable) {
    return function (dictFunctor) {
        return function (dictBoundedEnum) {
            var go = function (step) {
                return function (to) {
                    return function (e) {
                        if (e <= to) {
                            return new Data_Maybe.Just(new Data_Tuple.Tuple(e, e + step | 0));
                        };
                        if (Data_Boolean.otherwise) {
                            return Data_Maybe.Nothing.value;
                        };
                        throw new Error("Failed pattern match at Data.Enum (line 217, column 5 - line 219, column 28): " + [ step.constructor.name, to.constructor.name, e.constructor.name ]);
                    };
                };
            };
            return function (a) {
                return function (b) {
                    return function (c) {
                        var c$prime = fromEnum(dictBoundedEnum)(c);
                        var b$prime = fromEnum(dictBoundedEnum)(b);
                        var a$prime = fromEnum(dictBoundedEnum)(a);
                        return Data_Functor.map(dictFunctor)((function () {
                            var $102 = Data_Maybe.fromJust();
                            var $103 = toEnum(dictBoundedEnum);
                            return function ($104) {
                                return $102($103($104));
                            };
                        })())(Data_Unfoldable.unfoldr(dictUnfoldable)(go(b$prime - a$prime | 0)(c$prime))(a$prime));
                    };
                };
            };
        };
    };
};
var enumEither = function (dictBoundedEnum) {
    return function (dictBoundedEnum1) {
        return {
            succ: function (v) {
                if (v instanceof Data_Either.Left) {
                    return Data_Maybe.maybe(new Data_Maybe.Just(new Data_Either.Right(Data_Bounded.bottom(dictBoundedEnum1.Bounded0()))))(function ($105) {
                        return Data_Maybe.Just.create(Data_Either.Left.create($105));
                    })(succ(dictBoundedEnum.Enum1())(v.value0));
                };
                if (v instanceof Data_Either.Right) {
                    return Data_Maybe.maybe(Data_Maybe.Nothing.value)(function ($106) {
                        return Data_Maybe.Just.create(Data_Either.Right.create($106));
                    })(succ(dictBoundedEnum1.Enum1())(v.value0));
                };
                throw new Error("Failed pattern match at Data.Enum (line 86, column 1 - line 90, column 69): " + [ v.constructor.name ]);
            },
            pred: function (v) {
                if (v instanceof Data_Either.Left) {
                    return Data_Maybe.maybe(Data_Maybe.Nothing.value)(function ($107) {
                        return Data_Maybe.Just.create(Data_Either.Left.create($107));
                    })(pred(dictBoundedEnum.Enum1())(v.value0));
                };
                if (v instanceof Data_Either.Right) {
                    return Data_Maybe.maybe(new Data_Maybe.Just(new Data_Either.Left(Data_Bounded.top(dictBoundedEnum.Bounded0()))))(function ($108) {
                        return Data_Maybe.Just.create(Data_Either.Right.create($108));
                    })(pred(dictBoundedEnum1.Enum1())(v.value0));
                };
                throw new Error("Failed pattern match at Data.Enum (line 86, column 1 - line 90, column 69): " + [ v.constructor.name ]);
            },
            Ord0: function () {
                return Data_Either.ordEither((dictBoundedEnum.Enum1()).Ord0())((dictBoundedEnum1.Enum1()).Ord0());
            }
        };
    };
};
var enumBoolean = {
    succ: function (v) {
        if (!v) {
            return new Data_Maybe.Just(true);
        };
        return Data_Maybe.Nothing.value;
    },
    pred: function (v) {
        if (v) {
            return new Data_Maybe.Just(false);
        };
        return Data_Maybe.Nothing.value;
    },
    Ord0: function () {
        return Data_Ord.ordBoolean;
    }
};
var downFromIncluding = function (dictEnum) {
    return function (dictUnfoldable1) {
        return Data_Unfoldable1.unfoldr1(dictUnfoldable1)(Control_Apply.apply(Control_Apply.applyFn)(Data_Tuple.Tuple.create)(pred(dictEnum)));
    };
};
var diag = function (a) {
    return new Data_Tuple.Tuple(a, a);
};
var downFrom = function (dictEnum) {
    return function (dictUnfoldable) {
        return Data_Unfoldable.unfoldr(dictUnfoldable)((function () {
            var $109 = Data_Functor.map(Data_Maybe.functorMaybe)(diag);
            var $110 = pred(dictEnum);
            return function ($111) {
                return $109($110($111));
            };
        })());
    };
};
var upFrom = function (dictEnum) {
    return function (dictUnfoldable) {
        return Data_Unfoldable.unfoldr(dictUnfoldable)((function () {
            var $112 = Data_Functor.map(Data_Maybe.functorMaybe)(diag);
            var $113 = succ(dictEnum);
            return function ($114) {
                return $112($113($114));
            };
        })());
    };
};
var defaultToEnum = function (dictBounded) {
    return function (dictEnum) {
        return function (i$prime) {
            var go = function ($copy_i) {
                return function ($copy_x) {
                    var $tco_var_i = $copy_i;
                    var $tco_done = false;
                    var $tco_result;
                    function $tco_loop(i, x) {
                        var $83 = i === 0;
                        if ($83) {
                            $tco_done = true;
                            return new Data_Maybe.Just(x);
                        };
                        var v = succ(dictEnum)(x);
                        if (v instanceof Data_Maybe.Just) {
                            $tco_var_i = i - 1 | 0;
                            $copy_x = v.value0;
                            return;
                        };
                        if (v instanceof Data_Maybe.Nothing) {
                            $tco_done = true;
                            return Data_Maybe.Nothing.value;
                        };
                        throw new Error("Failed pattern match at Data.Enum (line 296, column 12 - line 298, column 33): " + [ v.constructor.name ]);
                    };
                    while (!$tco_done) {
                        $tco_result = $tco_loop($tco_var_i, $copy_x);
                    };
                    return $tco_result;
                };
            };
            var $86 = i$prime < 0;
            if ($86) {
                return Data_Maybe.Nothing.value;
            };
            return go(i$prime)(Data_Bounded.bottom(dictBounded));
        };
    };
};
var defaultSucc = function (toEnum$prime) {
    return function (fromEnum$prime) {
        return function (a) {
            return toEnum$prime(fromEnum$prime(a) + 1 | 0);
        };
    };
};
var defaultPred = function (toEnum$prime) {
    return function (fromEnum$prime) {
        return function (a) {
            return toEnum$prime(fromEnum$prime(a) - 1 | 0);
        };
    };
};
var defaultFromEnum = function (dictEnum) {
    var go = function ($copy_i) {
        return function ($copy_x) {
            var $tco_var_i = $copy_i;
            var $tco_done = false;
            var $tco_result;
            function $tco_loop(i, x) {
                var v = pred(dictEnum)(x);
                if (v instanceof Data_Maybe.Just) {
                    $tco_var_i = i + 1 | 0;
                    $copy_x = v.value0;
                    return;
                };
                if (v instanceof Data_Maybe.Nothing) {
                    $tco_done = true;
                    return i;
                };
                throw new Error("Failed pattern match at Data.Enum (line 309, column 5 - line 311, column 19): " + [ v.constructor.name ]);
            };
            while (!$tco_done) {
                $tco_result = $tco_loop($tco_var_i, $copy_x);
            };
            return $tco_result;
        };
    };
    return go(0);
};
var defaultCardinality = function (dictBounded) {
    return function (dictEnum) {
        var go = function ($copy_i) {
            return function ($copy_x) {
                var $tco_var_i = $copy_i;
                var $tco_done = false;
                var $tco_result;
                function $tco_loop(i, x) {
                    var v = succ(dictEnum)(x);
                    if (v instanceof Data_Maybe.Just) {
                        $tco_var_i = i + 1 | 0;
                        $copy_x = v.value0;
                        return;
                    };
                    if (v instanceof Data_Maybe.Nothing) {
                        $tco_done = true;
                        return i;
                    };
                    throw new Error("Failed pattern match at Data.Enum (line 276, column 5 - line 278, column 19): " + [ v.constructor.name ]);
                };
                while (!$tco_done) {
                    $tco_result = $tco_loop($tco_var_i, $copy_x);
                };
                return $tco_result;
            };
        };
        return Cardinality(go(1)(Data_Bounded.bottom(dictBounded)));
    };
};
var charToEnum = function (v) {
    if (v >= Data_Bounded.bottom(Data_Bounded.boundedInt) && v <= Data_Bounded.top(Data_Bounded.boundedInt)) {
        return new Data_Maybe.Just($foreign.fromCharCode(v));
    };
    return Data_Maybe.Nothing.value;
};
var enumChar = {
    succ: defaultSucc(charToEnum)($foreign.toCharCode),
    pred: defaultPred(charToEnum)($foreign.toCharCode),
    Ord0: function () {
        return Data_Ord.ordChar;
    }
};
var cardinality = function (dict) {
    return dict.cardinality;
};
var boundedEnumUnit = {
    cardinality: 1,
    toEnum: function (v) {
        if (v === 0) {
            return new Data_Maybe.Just(Data_Unit.unit);
        };
        return Data_Maybe.Nothing.value;
    },
    fromEnum: Data_Function["const"](0),
    Bounded0: function () {
        return Data_Bounded.boundedUnit;
    },
    Enum1: function () {
        return enumUnit;
    }
};
var boundedEnumOrdering = {
    cardinality: 3,
    toEnum: function (v) {
        if (v === 0) {
            return new Data_Maybe.Just(Data_Ordering.LT.value);
        };
        if (v === 1) {
            return new Data_Maybe.Just(Data_Ordering.EQ.value);
        };
        if (v === 2) {
            return new Data_Maybe.Just(Data_Ordering.GT.value);
        };
        return Data_Maybe.Nothing.value;
    },
    fromEnum: function (v) {
        if (v instanceof Data_Ordering.LT) {
            return 0;
        };
        if (v instanceof Data_Ordering.EQ) {
            return 1;
        };
        if (v instanceof Data_Ordering.GT) {
            return 2;
        };
        throw new Error("Failed pattern match at Data.Enum (line 137, column 1 - line 145, column 18): " + [ v.constructor.name ]);
    },
    Bounded0: function () {
        return Data_Bounded.boundedOrdering;
    },
    Enum1: function () {
        return enumOrdering;
    }
};
var boundedEnumChar = {
    cardinality: $foreign.toCharCode(Data_Bounded.top(Data_Bounded.boundedChar)) - $foreign.toCharCode(Data_Bounded.bottom(Data_Bounded.boundedChar)) | 0,
    toEnum: charToEnum,
    fromEnum: $foreign.toCharCode,
    Bounded0: function () {
        return Data_Bounded.boundedChar;
    },
    Enum1: function () {
        return enumChar;
    }
};
var boundedEnumBoolean = {
    cardinality: 2,
    toEnum: function (v) {
        if (v === 0) {
            return new Data_Maybe.Just(false);
        };
        if (v === 1) {
            return new Data_Maybe.Just(true);
        };
        return Data_Maybe.Nothing.value;
    },
    fromEnum: function (v) {
        if (!v) {
            return 0;
        };
        if (v) {
            return 1;
        };
        throw new Error("Failed pattern match at Data.Enum (line 118, column 1 - line 124, column 20): " + [ v.constructor.name ]);
    },
    Bounded0: function () {
        return Data_Bounded.boundedBoolean;
    },
    Enum1: function () {
        return enumBoolean;
    }
};
module.exports = {
    succ: succ,
    pred: pred,
    cardinality: cardinality,
    toEnum: toEnum,
    fromEnum: fromEnum,
    toEnumWithDefaults: toEnumWithDefaults,
    Cardinality: Cardinality,
    enumFromTo: enumFromTo,
    enumFromThenTo: enumFromThenTo,
    upFrom: upFrom,
    upFromIncluding: upFromIncluding,
    downFrom: downFrom,
    downFromIncluding: downFromIncluding,
    defaultSucc: defaultSucc,
    defaultPred: defaultPred,
    defaultCardinality: defaultCardinality,
    defaultToEnum: defaultToEnum,
    defaultFromEnum: defaultFromEnum,
    enumBoolean: enumBoolean,
    enumInt: enumInt,
    enumChar: enumChar,
    enumUnit: enumUnit,
    enumOrdering: enumOrdering,
    enumMaybe: enumMaybe,
    enumEither: enumEither,
    enumTuple: enumTuple,
    boundedEnumBoolean: boundedEnumBoolean,
    boundedEnumChar: boundedEnumChar,
    boundedEnumUnit: boundedEnumUnit,
    boundedEnumOrdering: boundedEnumOrdering,
    newtypeCardinality: newtypeCardinality,
    eqCardinality: eqCardinality,
    ordCardinality: ordCardinality,
    showCardinality: showCardinality
};
