// Generated by purs version 0.12.5
"use strict";
var Control_Applicative = require("../Control.Applicative/index.js");
var Control_Bind = require("../Control.Bind/index.js");
var Data_Boolean = require("../Data.Boolean/index.js");
var Data_Decimal = require("../Data.Decimal/index.js");
var Data_Either = require("../Data.Either/index.js");
var Data_Eq = require("../Data.Eq/index.js");
var Data_EuclideanRing = require("../Data.EuclideanRing/index.js");
var Data_Foldable = require("../Data.Foldable/index.js");
var Data_Function = require("../Data.Function/index.js");
var Data_Functor = require("../Data.Functor/index.js");
var Data_List_Types = require("../Data.List.Types/index.js");
var Data_Number_Approximate = require("../Data.Number.Approximate/index.js");
var Data_Ord = require("../Data.Ord/index.js");
var Data_Ring = require("../Data.Ring/index.js");
var Data_Semigroup = require("../Data.Semigroup/index.js");
var Data_Semiring = require("../Data.Semiring/index.js");
var Data_Show = require("../Data.Show/index.js");
var Data_Tuple = require("../Data.Tuple/index.js");
var Data_Units = require("../Data.Units/index.js");
var Data_Units_SI_Accepted = require("../Data.Units.SI.Accepted/index.js");
var Data_Units_SI_Derived = require("../Data.Units.SI.Derived/index.js");
var Quantity = (function () {
    function Quantity(value0, value1) {
        this.value0 = value0;
        this.value1 = value1;
    };
    Quantity.create = function (value0) {
        return function (value1) {
            return new Quantity(value0, value1);
        };
    };
    return Quantity;
})();
var ConversionError = (function () {
    function ConversionError(value0, value1) {
        this.value0 = value0;
        this.value1 = value1;
    };
    ConversionError.create = function (value0) {
        return function (value1) {
            return new ConversionError(value0, value1);
        };
    };
    return ConversionError;
})();
var value = function (v) {
    return v.value0;
};
var showQuantity = new Data_Show.Show(function (v) {
    return Data_Show.show(Data_Decimal.showDecimal)(v.value0) + (" .* " + Data_Show.show(Data_Units.showDerivedUnit)(v.value1));
});
var showConversionError = new Data_Show.Show(function (v) {
    return "ConversionError (" + (Data_Show.show(Data_Units.showDerivedUnit)(v.value0) + (")" + (" (" + (Data_Show.show(Data_Units.showDerivedUnit)(v.value1) + ")"))));
});
var quantity$prime = function (n) {
    return function (du) {
        return new Quantity(n, du);
    };
};
var scalar$prime = function (factor) {
    return quantity$prime(factor)(Data_Units.unity);
};
var toStandard = function (v) {
    var v1 = Data_Units.toStandardUnit(v.value1);
    return quantity$prime(Data_Semiring.mul(Data_Decimal.semiringDecimal)(v1.value1)(v.value0))(v1.value0);
};
var quantity = function (n) {
    return function (du) {
        return new Quantity(Data_Decimal.fromNumber(n), du);
    };
};
var scalar = function (factor) {
    return quantity(factor)(Data_Units.unity);
};
var qNegate = function (v) {
    return new Quantity(Data_Ring.negate(Data_Decimal.ringDecimal)(v.value0), v.value1);
};
var qMultiply = function (v) {
    return function (v1) {
        return quantity$prime(Data_Semiring.mul(Data_Decimal.semiringDecimal)(v.value0)(v1.value0))(Data_Semigroup.append(Data_Units.semigroupDerivedUnit)(v.value1)(v1.value1));
    };
};
var qDivide = function (v) {
    return function (v1) {
        return quantity$prime(Data_EuclideanRing.div(Data_Decimal.euclideanRingDecimal)(v.value0)(v1.value0))(Data_Units.divideUnits(v.value1)(v1.value1));
    };
};
var prettyDecimal = function (d) {
    var $64 = Data_Decimal.isInteger(d) && Data_Ord.lessThan(Data_Decimal.ordDecimal)(d)(Data_Decimal.fromNumber(1.0e18));
    if ($64) {
        return Data_Decimal.toString(d);
    };
    return Data_Decimal.toString(Data_Decimal.toSignificantDigits(6)(d));
};
var prettyPrint$prime = function (v) {
    if (Data_Eq.eq(Data_Units.eqDerivedUnit)(v.value1)(Data_Units.unity)) {
        return {
            number: prettyDecimal(v.value0),
            space: false,
            unit: ""
        };
    };
    if (Data_Boolean.otherwise) {
        var space = Data_Eq.notEq(Data_Units.eqDerivedUnit)(v.value1)(Data_Units_SI_Accepted.degree);
        return {
            number: prettyDecimal(v.value0),
            space: space,
            unit: Data_Units.toString(v.value1)
        };
    };
    throw new Error("Failed pattern match at Data.Quantity (line 105, column 1 - line 105, column 78): " + [ v.constructor.name ]);
};
var prettyPrint = function (q) {
    var v = prettyPrint$prime(q);
    var space = (function () {
        if (v.space) {
            return " ";
        };
        return "";
    })();
    return v.number + (space + v.unit);
};
var pow = function (v) {
    return function (exp) {
        return quantity$prime(Data_Decimal.pow(v.value0)(exp))(Data_Units.power(v.value1)(Data_Decimal.toNumber(exp)));
    };
};
var sqrt = function (q) {
    return pow(q)(Data_Decimal.fromNumber(0.5));
};
var $$isFinite = function (v) {
    return Data_Decimal["isFinite"](v.value0);
};
var errorMessage = function (v) {
    var baseRep = function (u) {
        var u$prime = Data_Tuple.fst(Data_Units.toStandardUnit(u));
        var $78 = Data_Eq.eq(Data_Units.eqDerivedUnit)(u$prime)(Data_Units.unity);
        if ($78) {
            return "";
        };
        return " (SI: '" + (Data_Units.toString(u$prime) + "')");
    };
    var $79 = Data_Eq.eq(Data_Units.eqDerivedUnit)(v.value0)(Data_Units.unity);
    if ($79) {
        return "Cannot convert quantity of unit '" + (Data_Units.toString(v.value1) + "' to a scalar");
    };
    var $80 = Data_Eq.eq(Data_Units.eqDerivedUnit)(v.value1)(Data_Units.unity);
    if ($80) {
        return "Cannot convert quantity of unit '" + (Data_Units.toString(v.value0) + "' to a scalar");
    };
    return "Cannot convert unit '" + (Data_Units.toString(v.value0) + ("'" + (baseRep(v.value0) + ("\x0a" + ("            to unit '" + (Data_Units.toString(v.value1) + ("'" + (baseRep(v.value1) + ""))))))));
};
var showResult = function (v) {
    if (v instanceof Data_Either.Left) {
        return errorMessage(v.value0);
    };
    if (v instanceof Data_Either.Right) {
        return prettyPrint(v.value0);
    };
    throw new Error("Failed pattern match at Data.Quantity (line 120, column 1 - line 120, column 54): " + [ v.constructor.name ]);
};
var eqConversionError = new Data_Eq.Eq(function (x) {
    return function (y) {
        return Data_Eq.eq(Data_Units.eqDerivedUnit)(x.value0)(y.value0) && Data_Eq.eq(Data_Units.eqDerivedUnit)(x.value1)(y.value1);
    };
});
var derivedUnit = function (v) {
    return v.value1;
};
var eqQuantity = new Data_Eq.Eq(function (q1) {
    return function (q2) {
        var q2$prime = toStandard(q2);
        var u2 = derivedUnit(q2$prime);
        var v2 = value(q2$prime);
        var q1$prime = toStandard(q1);
        var u1 = derivedUnit(q1$prime);
        var v1 = value(q1$prime);
        return Data_Eq.eq(Data_Decimal.eqDecimal)(v1)(v2) && Data_Eq.eq(Data_Units.eqDerivedUnit)(u1)(u2) || Data_Eq.eq(Data_Decimal.eqDecimal)(v1)(Data_Semiring.zero(Data_Decimal.semiringDecimal)) && Data_Eq.eq(Data_Decimal.eqDecimal)(v2)(Data_Semiring.zero(Data_Decimal.semiringDecimal));
    };
});
var convert = function (to) {
    return function (v) {
        if (Data_Eq.eq(Data_Units.eqDerivedUnit)(to)(v.value1)) {
            return new Data_Either.Right(v);
        };
        if (Data_Eq.eq(Data_Decimal.eqDecimal)(v.value0)(Data_Semiring.zero(Data_Decimal.semiringDecimal))) {
            return new Data_Either.Right(new Quantity(Data_Semiring.zero(Data_Decimal.semiringDecimal), to));
        };
        if (Data_Boolean.otherwise) {
            var v1 = Data_Units.toStandardUnit(to);
            var q$prime = toStandard(v);
            var from$prime = derivedUnit(q$prime);
            var $98 = Data_Eq.eq(Data_Units.eqDerivedUnit)(from$prime)(v1.value0);
            if ($98) {
                return Data_Either.Right.create(new Quantity(Data_EuclideanRing.div(Data_Decimal.euclideanRingDecimal)(q$prime.value0)(v1.value1), to));
            };
            return Data_Either.Left.create(new ConversionError(v.value1, to));
        };
        throw new Error("Failed pattern match at Data.Quantity (line 215, column 1 - line 215, column 67): " + [ to.constructor.name, v.constructor.name ]);
    };
};
var convertTo = Data_Function.flip(convert);
var qAdd = function (v) {
    return function (v1) {
        if (Data_Eq.eq(Data_Decimal.eqDecimal)(v.value0)(Data_Semiring.zero(Data_Decimal.semiringDecimal))) {
            return Control_Applicative.pure(Data_Either.applicativeEither)(v1);
        };
        if (Data_Eq.eq(Data_Decimal.eqDecimal)(v1.value0)(Data_Semiring.zero(Data_Decimal.semiringDecimal))) {
            return Control_Applicative.pure(Data_Either.applicativeEither)(v);
        };
        if (Data_Boolean.otherwise) {
            return Control_Bind.bind(Data_Either.bindEither)(convertTo(v1)(v.value1))(function (v3) {
                return Control_Applicative.pure(Data_Either.applicativeEither)(quantity$prime(Data_Semiring.add(Data_Decimal.semiringDecimal)(v.value0)(v3.value0))(v.value1));
            });
        };
        throw new Error("Failed pattern match at Data.Quantity (line 262, column 1 - line 262, column 61): " + [ v.constructor.name, v1.constructor.name ]);
    };
};
var qSubtract = function (q1) {
    return function (v) {
        return qAdd(q1)(new Quantity(Data_Ring.negate(Data_Decimal.ringDecimal)(v.value0), v.value1));
    };
};
var asValueIn$prime = function (u) {
    return Control_Bind.composeKleisli(Data_Either.bindEither)(convertTo(u))(function ($138) {
        return Control_Applicative.pure(Data_Either.applicativeEither)(value($138));
    });
};
var toScalar$prime = function (q) {
    return asValueIn$prime(q)(Data_Units.unity);
};
var fullSimplify = function (v) {
    var v1 = toScalar$prime(v);
    if (v1 instanceof Data_Either.Right) {
        var $122 = Data_Eq.notEq(Data_Units.eqDerivedUnit)(Data_Units.removePrefix(v.value1))(Data_Units_SI_Accepted.degree) && Data_Eq.notEq(Data_Units.eqDerivedUnit)(Data_Units.removePrefix(v.value1))(Data_Units_SI_Derived.radian);
        if ($122) {
            return new Quantity(v1.value0, Data_Units.unity);
        };
        return quantity$prime(v.value0)(v.value1);
    };
    if (v1 instanceof Data_Either.Left) {
        var toTuple = function (v2) {
            var v3 = convertTo(quantity(1)(v2.value1))(v2.value0);
            if (v3 instanceof Data_Either.Right) {
                return new Data_Tuple.Tuple(v3.value0.value0, v3.value0.value1);
            };
            if (v3 instanceof Data_Either.Left) {
                return new Data_Tuple.Tuple(Data_Semiring.one(Data_Decimal.semiringDecimal), v2.value0);
            };
            throw new Error("Failed pattern match at Data.Quantity (line 151, column 13 - line 153, column 55): " + [ v3.constructor.name ]);
        };
        var list = Data_Units.splitByDimension(v.value1);
        var list$prime = Data_Functor.map(Data_List_Types.functorList)(toTuple)(list);
        var factor = Data_Foldable.product(Data_List_Types.foldableList)(Data_Decimal.semiringDecimal)(Data_Functor.map(Data_List_Types.functorList)(Data_Tuple.fst)(list$prime));
        var du$prime = Data_Foldable.foldMap(Data_List_Types.foldableList)(Data_Units.monoidDerivedUnit)(Data_Tuple.snd)(list$prime);
        return new Quantity(Data_Semiring.mul(Data_Decimal.semiringDecimal)(v.value0)(factor), du$prime);
    };
    throw new Error("Failed pattern match at Data.Quantity (line 142, column 3 - line 160, column 32): " + [ v1.constructor.name ]);
};
var asValueIn = function (q) {
    return function (u) {
        return Data_Functor.map(Data_Either.functorEither)(Data_Decimal.toNumber)(asValueIn$prime(q)(u));
    };
};
var toScalar = function (q) {
    return asValueIn(q)(Data_Units.unity);
};
var approximatelyEqual = function (tol) {
    return function (q1$prime) {
        return function (q2$prime) {
            var q2 = toStandard(q2$prime);
            var v2 = Data_Decimal.toNumber(value(q2));
            var q1 = toStandard(q1$prime);
            var v1 = Data_Decimal.toNumber(value(q1));
            return Data_Eq.eq(Data_Units.eqDerivedUnit)(derivedUnit(q1))(derivedUnit(q2)) && Data_Number_Approximate.eqRelative(tol)(v1)(v2);
        };
    };
};
var abs = function (v) {
    return quantity$prime(Data_Decimal.abs(v.value0))(v.value1);
};
module.exports = {
    quantity: quantity,
    "quantity'": quantity$prime,
    "prettyPrint'": prettyPrint$prime,
    prettyPrint: prettyPrint,
    showResult: showResult,
    derivedUnit: derivedUnit,
    toStandard: toStandard,
    fullSimplify: fullSimplify,
    approximatelyEqual: approximatelyEqual,
    ConversionError: ConversionError,
    errorMessage: errorMessage,
    scalar: scalar,
    "scalar'": scalar$prime,
    convert: convert,
    convertTo: convertTo,
    asValueIn: asValueIn,
    "asValueIn'": asValueIn$prime,
    toScalar: toScalar,
    "toScalar'": toScalar$prime,
    "isFinite": $$isFinite,
    qNegate: qNegate,
    qAdd: qAdd,
    qSubtract: qSubtract,
    qMultiply: qMultiply,
    qDivide: qDivide,
    pow: pow,
    abs: abs,
    sqrt: sqrt,
    eqQuantity: eqQuantity,
    showQuantity: showQuantity,
    eqConversionError: eqConversionError,
    showConversionError: showConversionError
};
