module Duration.POrd where
class POrd a where
partialCompare :: a -> a -> Maybe Ordering
pLeq :: a -> a -> Bool
pLeq x y = case (partialCompare x y) of
Just LT -> True
Just EQ -> True
_ -> False
partialCompare x y = case (pLeq x y,pLeq y x) of
(True,True) -> Just EQ
(True,False) -> Just LT
(False,True) -> Just GT
(False,False) -> Nothing
pOrdEq :: a -> a -> Bool
pOrdEq a1 a2
= case partialCompare a1 a2 of
Just EQ -> True
_ -> False
pOrdMin :: [a] -> Maybe a
pOrdMin [] = Nothing
pOrdMin [x] = Just x
pOrdMin (x:y:ys)
= case pOrdMin (y:ys) of
Nothing -> Nothing
Just z -> case (partialCompare x z) of
Nothing -> Nothing
Just LT -> Just x
_ -> Just z
pOrdMax :: [a] -> Maybe a
pOrdMax [] = Nothing
pOrdMax [x] = Just x
pOrdMax (x:y:ys)
= case pOrdMax (y:ys) of
Nothing -> Nothing
Just z -> case (partialCompare x z) of
Nothing -> Nothing
Just GT -> Just x
_ -> Just z
pOrdReduceMin :: (POrd a) => [a] -> [a]
pOrdReduceMin [] = []
pOrdReduceMin (x:xs)
= let rxs = pOrdReduceMin xs
in case rxs of
[] -> [x]
(y:ys) -> case partialCompare x y of
Nothing -> y:pOrdReduceMin (x:ys)
Just LT -> pOrdReduceMin (x:ys)
_ -> y:ys
pOrdReduceMax :: (POrd a) => [a] -> [a]
pOrdReduceMax [] = []
pOrdReduceMax (x:xs)
= let rxs = pOrdReduceMax xs
in case rxs of
[] -> [x]
(y:ys) -> case partialCompare x y of
Nothing -> y:pOrdReduceMax (x:ys)
Just GT -> pOrdReduceMax (x:ys)
_ -> y:ys
instance POrd () where
partialCompare x y = Just $ compare x y
instance POrd Integer where
partialCompare x y = Just $ compare x y
instance POrd Int where
partialCompare x y = Just $ compare x y
instance POrd Char where
partialCompare x y = Just $ compare x y
instance POrd Rational where
partialCompare x y = Just $ compare x y
instance (POrd a,POrd b) => POrd (Either a b) where
partialCompare (Left a1) (Left a2) = partialCompare a1 a2
partialCompare (Right b1) (Right b2) = partialCompare b1 b2
partialCompare _ _ = Nothing
instance (POrd a,POrd b) => POrd (a,b) where
partialCompare (a1,b1) (a2,b2)
= case (partialCompare a1 a2,partialCompare b1 b2) of
(Just EQ, r) -> r
(r,Just EQ) -> r
(Just LT,Just LT) -> Just LT
(Just GT,Just GT) -> Just GT
_ -> Nothing