module Data.Ord.Bounded (
GBounded
,BoundedMin
,BoundedMax
,BoundedBoth
,minimumBound
,maximumBound
) where
import Control.Applicative
import Data.Void
data GBounded min max a = MinimumB min | ValueB a | MaximumB max deriving (Show, Eq)
type BoundedMin = GBounded () Void
type BoundedMax = GBounded Void ()
type BoundedBoth = GBounded () ()
minimumBound :: GBounded () max a
minimumBound = MinimumB ()
maximumBound :: GBounded min () a
maximumBound = MaximumB ()
instance Functor (GBounded min max) where
fmap f (ValueB a) = ValueB (f a)
fmap _ (MinimumB v) = MinimumB v
fmap _ (MaximumB v) = MaximumB v
instance Applicative (GBounded min max) where
pure = ValueB
ValueB f <*> ValueB x = ValueB (f x)
MinimumB v <*> _ = MinimumB v
MaximumB v <*> _ = MaximumB v
instance Monad (GBounded min max) where
return = ValueB
ValueB x >>= k = k x
MinimumB v >>= _ = MinimumB v
MaximumB v >>= _ = MaximumB v
instance (Ord min, Ord max, Ord a) => Ord (GBounded min max a) where
ValueB a `compare` ValueB b = compare a b
MinimumB v `compare` MinimumB w = compare v w
MaximumB v `compare` MaximumB w = compare v w
MinimumB _ `compare` _ = LT
_ `compare` MinimumB _ = GT
MaximumB _ `compare` _ = GT
_ `compare` MaximumB _ = LT