{-# LANGUAGE FlexibleInstances #-}

module Data.Ord.Extended (
      between
    , Min(..)
    , Max(..)
    , MinMax(..)
    , module Data.Ord
) where

import Data.Ord

-- | Is the value between two other values?
between :: Ord a => (a, a) -> a -> Bool
between :: forall a. Ord a => (a, a) -> a -> Bool
between (a
a,a
b) a
x = a -> a -> a
forall a. Ord a => a -> a -> a
min a
a a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
x Bool -> Bool -> Bool
&& a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a -> a -> a
forall a. Ord a => a -> a -> a
max a
a a
b

infinity :: Double
infinity :: Double
infinity = Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
0

-- | 'Monoid' to calculate the minimum.
newtype Min a = Min a deriving (Min a -> Min a -> Bool
(Min a -> Min a -> Bool) -> (Min a -> Min a -> Bool) -> Eq (Min a)
forall a. Eq a => Min a -> Min a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Min a -> Min a -> Bool
== :: Min a -> Min a -> Bool
$c/= :: forall a. Eq a => Min a -> Min a -> Bool
/= :: Min a -> Min a -> Bool
Eq, Eq (Min a)
Eq (Min a)
-> (Min a -> Min a -> Ordering)
-> (Min a -> Min a -> Bool)
-> (Min a -> Min a -> Bool)
-> (Min a -> Min a -> Bool)
-> (Min a -> Min a -> Bool)
-> (Min a -> Min a -> Min a)
-> (Min a -> Min a -> Min a)
-> Ord (Min a)
Min a -> Min a -> Bool
Min a -> Min a -> Ordering
Min a -> Min a -> Min a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (Min a)
forall a. Ord a => Min a -> Min a -> Bool
forall a. Ord a => Min a -> Min a -> Ordering
forall a. Ord a => Min a -> Min a -> Min a
$ccompare :: forall a. Ord a => Min a -> Min a -> Ordering
compare :: Min a -> Min a -> Ordering
$c< :: forall a. Ord a => Min a -> Min a -> Bool
< :: Min a -> Min a -> Bool
$c<= :: forall a. Ord a => Min a -> Min a -> Bool
<= :: Min a -> Min a -> Bool
$c> :: forall a. Ord a => Min a -> Min a -> Bool
> :: Min a -> Min a -> Bool
$c>= :: forall a. Ord a => Min a -> Min a -> Bool
>= :: Min a -> Min a -> Bool
$cmax :: forall a. Ord a => Min a -> Min a -> Min a
max :: Min a -> Min a -> Min a
$cmin :: forall a. Ord a => Min a -> Min a -> Min a
min :: Min a -> Min a -> Min a
Ord, Int -> Min a -> ShowS
[Min a] -> ShowS
Min a -> String
(Int -> Min a -> ShowS)
-> (Min a -> String) -> ([Min a] -> ShowS) -> Show (Min a)
forall a. Show a => Int -> Min a -> ShowS
forall a. Show a => [Min a] -> ShowS
forall a. Show a => Min a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Min a -> ShowS
showsPrec :: Int -> Min a -> ShowS
$cshow :: forall a. Show a => Min a -> String
show :: Min a -> String
$cshowList :: forall a. Show a => [Min a] -> ShowS
showList :: [Min a] -> ShowS
Show)
instance Ord a => Semigroup (Min a) where Min a
min1 <> :: Min a -> Min a -> Min a
<> Min a
min2 = a -> Min a
forall a. a -> Min a
Min (a -> a -> a
forall a. Ord a => a -> a -> a
min a
min1 a
min2)
-- | 'mempty' = \(\infty\)
instance {-# OVERLAPPING #-} Monoid (Min Double) where mempty :: Min Double
mempty = Double -> Min Double
forall a. a -> Min a
Min Double
infinity
instance {-# OVERLAPPABLE #-} (Bounded a, Ord a) => Monoid (Min a) where mempty :: Min a
mempty = a -> Min a
forall a. a -> Min a
Min a
forall a. Bounded a => a
maxBound

-- | 'Monoid' to calculate the maximum.
newtype Max a = Max a deriving (Max a -> Max a -> Bool
(Max a -> Max a -> Bool) -> (Max a -> Max a -> Bool) -> Eq (Max a)
forall a. Eq a => Max a -> Max a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Max a -> Max a -> Bool
== :: Max a -> Max a -> Bool
$c/= :: forall a. Eq a => Max a -> Max a -> Bool
/= :: Max a -> Max a -> Bool
Eq, Eq (Max a)
Eq (Max a)
-> (Max a -> Max a -> Ordering)
-> (Max a -> Max a -> Bool)
-> (Max a -> Max a -> Bool)
-> (Max a -> Max a -> Bool)
-> (Max a -> Max a -> Bool)
-> (Max a -> Max a -> Max a)
-> (Max a -> Max a -> Max a)
-> Ord (Max a)
Max a -> Max a -> Bool
Max a -> Max a -> Ordering
Max a -> Max a -> Max a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (Max a)
forall a. Ord a => Max a -> Max a -> Bool
forall a. Ord a => Max a -> Max a -> Ordering
forall a. Ord a => Max a -> Max a -> Max a
$ccompare :: forall a. Ord a => Max a -> Max a -> Ordering
compare :: Max a -> Max a -> Ordering
$c< :: forall a. Ord a => Max a -> Max a -> Bool
< :: Max a -> Max a -> Bool
$c<= :: forall a. Ord a => Max a -> Max a -> Bool
<= :: Max a -> Max a -> Bool
$c> :: forall a. Ord a => Max a -> Max a -> Bool
> :: Max a -> Max a -> Bool
$c>= :: forall a. Ord a => Max a -> Max a -> Bool
>= :: Max a -> Max a -> Bool
$cmax :: forall a. Ord a => Max a -> Max a -> Max a
max :: Max a -> Max a -> Max a
$cmin :: forall a. Ord a => Max a -> Max a -> Max a
min :: Max a -> Max a -> Max a
Ord, Int -> Max a -> ShowS
[Max a] -> ShowS
Max a -> String
(Int -> Max a -> ShowS)
-> (Max a -> String) -> ([Max a] -> ShowS) -> Show (Max a)
forall a. Show a => Int -> Max a -> ShowS
forall a. Show a => [Max a] -> ShowS
forall a. Show a => Max a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Max a -> ShowS
showsPrec :: Int -> Max a -> ShowS
$cshow :: forall a. Show a => Max a -> String
show :: Max a -> String
$cshowList :: forall a. Show a => [Max a] -> ShowS
showList :: [Max a] -> ShowS
Show)
instance Ord a => Semigroup (Max a) where Max a
max1 <> :: Max a -> Max a -> Max a
<> Max a
max2 = a -> Max a
forall a. a -> Max a
Max (a -> a -> a
forall a. Ord a => a -> a -> a
max a
max1 a
max2)
-- | 'mempty' = \(-\infty\)
instance {-# OVERLAPPING #-} Monoid (Max Double) where mempty :: Max Double
mempty = Double -> Max Double
forall a. a -> Max a
Max (-Double
infinity)
instance {-# OVERLAPPABLE #-} (Bounded a, Ord a) => Monoid (Max a) where mempty :: Max a
mempty = a -> Max a
forall a. a -> Max a
Max a
forall a. Bounded a => a
minBound

-- | 'Semigroup' to calculate the minimum and maximum simultaneously.
data MinMax a = MinMax !a !a deriving (MinMax a -> MinMax a -> Bool
(MinMax a -> MinMax a -> Bool)
-> (MinMax a -> MinMax a -> Bool) -> Eq (MinMax a)
forall a. Eq a => MinMax a -> MinMax a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => MinMax a -> MinMax a -> Bool
== :: MinMax a -> MinMax a -> Bool
$c/= :: forall a. Eq a => MinMax a -> MinMax a -> Bool
/= :: MinMax a -> MinMax a -> Bool
Eq, Eq (MinMax a)
Eq (MinMax a)
-> (MinMax a -> MinMax a -> Ordering)
-> (MinMax a -> MinMax a -> Bool)
-> (MinMax a -> MinMax a -> Bool)
-> (MinMax a -> MinMax a -> Bool)
-> (MinMax a -> MinMax a -> Bool)
-> (MinMax a -> MinMax a -> MinMax a)
-> (MinMax a -> MinMax a -> MinMax a)
-> Ord (MinMax a)
MinMax a -> MinMax a -> Bool
MinMax a -> MinMax a -> Ordering
MinMax a -> MinMax a -> MinMax a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (MinMax a)
forall a. Ord a => MinMax a -> MinMax a -> Bool
forall a. Ord a => MinMax a -> MinMax a -> Ordering
forall a. Ord a => MinMax a -> MinMax a -> MinMax a
$ccompare :: forall a. Ord a => MinMax a -> MinMax a -> Ordering
compare :: MinMax a -> MinMax a -> Ordering
$c< :: forall a. Ord a => MinMax a -> MinMax a -> Bool
< :: MinMax a -> MinMax a -> Bool
$c<= :: forall a. Ord a => MinMax a -> MinMax a -> Bool
<= :: MinMax a -> MinMax a -> Bool
$c> :: forall a. Ord a => MinMax a -> MinMax a -> Bool
> :: MinMax a -> MinMax a -> Bool
$c>= :: forall a. Ord a => MinMax a -> MinMax a -> Bool
>= :: MinMax a -> MinMax a -> Bool
$cmax :: forall a. Ord a => MinMax a -> MinMax a -> MinMax a
max :: MinMax a -> MinMax a -> MinMax a
$cmin :: forall a. Ord a => MinMax a -> MinMax a -> MinMax a
min :: MinMax a -> MinMax a -> MinMax a
Ord, Int -> MinMax a -> ShowS
[MinMax a] -> ShowS
MinMax a -> String
(Int -> MinMax a -> ShowS)
-> (MinMax a -> String) -> ([MinMax a] -> ShowS) -> Show (MinMax a)
forall a. Show a => Int -> MinMax a -> ShowS
forall a. Show a => [MinMax a] -> ShowS
forall a. Show a => MinMax a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> MinMax a -> ShowS
showsPrec :: Int -> MinMax a -> ShowS
$cshow :: forall a. Show a => MinMax a -> String
show :: MinMax a -> String
$cshowList :: forall a. Show a => [MinMax a] -> ShowS
showList :: [MinMax a] -> ShowS
Show)
instance Ord a => Semigroup (MinMax a) where MinMax a
min1 a
max1 <> :: MinMax a -> MinMax a -> MinMax a
<> MinMax a
min2 a
max2 = a -> a -> MinMax a
forall a. a -> a -> MinMax a
MinMax (a -> a -> a
forall a. Ord a => a -> a -> a
min a
min1 a
min2) (a -> a -> a
forall a. Ord a => a -> a -> a
max a
max1 a
max2)
-- | 'mempty' = \((\infty, -\infty)\)
instance {-# OVERLAPPING #-} Monoid (MinMax Double) where mempty :: MinMax Double
mempty = Double -> Double -> MinMax Double
forall a. a -> a -> MinMax a
MinMax Double
infinity (-Double
infinity)
instance {-# OVERLAPPABLE #-} (Bounded a, Ord a) => Monoid (MinMax a) where mempty :: MinMax a
mempty = a -> a -> MinMax a
forall a. a -> a -> MinMax a
MinMax a
forall a. Bounded a => a
maxBound a
forall a. Bounded a => a
minBound