/**
* @since 0.24.0
*/
import type { TypeLambda } from "effect/HKT"
import * as order from "effect/Order"
import type { Order } from "effect/Order"
import type { Monoid } from "./Monoid.js"
import * as monoid from "./Monoid.js"
import * as semigroup from "./Semigroup.js"
/**
* @category type class
* @since 0.24.0
*/
export interface Bounded {
readonly compare: Order
readonly maxBound: A
readonly minBound: A
}
/**
* @category type lambdas
* @since 0.24.0
*/
export interface BoundedTypeLambda extends TypeLambda {
readonly type: Bounded
}
/**
* `Monoid` that returns last minimum of elements.
*
* @category constructors
* @since 0.24.0
*/
export const min = (B: Bounded): Monoid => monoid.fromSemigroup(semigroup.min(B.compare), B.maxBound)
/**
* `Monoid` that returns last maximum of elements.
*
* @category constructors
* @since 0.24.0
*/
export const max = (B: Bounded): Monoid => monoid.fromSemigroup(semigroup.max(B.compare), B.minBound)
/**
* Checks if a value is between the lower and upper limit of a bound.
*
* @category predicates
* @since 0.24.0
*/
export const between = (B: Bounded): (a: A) => boolean =>
order.between(B.compare)({ minimum: B.minBound, maximum: B.maxBound })
/**
* Clamp a value between `minBound` and `maxBound` values.
*
* @category utils
* @since 0.24.0
*/
export const clamp = (B: Bounded): (a: A) => A =>
order.clamp(B.compare)({ minimum: B.minBound, maximum: B.maxBound })
/**
* Reverses the `Order` of a `Bounded` and flips `maxBound` and `minBound` values.
*
* @category utils
* @since 0.24.0
*/
export const reverse = (B: Bounded): Bounded => ({
compare: order.reverse(B.compare),
minBound: B.maxBound,
maxBound: B.minBound
})