module Numeric.Order.Class ( Order(..) , orderOrd ) where import Data.Int import Data.Word import Numeric.Natural -- a partial order (a, <=) class Order a where (<~) :: a -> a -> Bool a <~ b = maybe False (<= EQ) (order a b) (<) :: a -> a -> Bool a < b = order a b == Just LT (>~) :: a -> a -> Bool a >~ b = b <~ a (>) :: a -> a -> Bool a > b = order a b == Just GT (~~) :: a -> a -> Bool a ~~ b = order a b == Just EQ (/~) :: a -> a -> Bool a /~ b = order a b /= Just EQ order :: a -> a -> Maybe Ordering order a b | a <~ b = Just $ if b <~ a then EQ else LT | b <~ a = Just GT | otherwise = Nothing comparable :: a -> a -> Bool comparable a b = maybe False (const True) (order a b) orderOrd :: Ord a => a -> a -> Maybe Ordering orderOrd a b = Just (compare a b) instance Order Bool where order = orderOrd instance Order Integer where order = orderOrd instance Order Int where order = orderOrd instance Order Int8 where order = orderOrd instance Order Int16 where order = orderOrd instance Order Int32 where order = orderOrd instance Order Int64 where order = orderOrd instance Order Natural where order = orderOrd instance Order Word where order = orderOrd instance Order Word8 where order = orderOrd instance Order Word16 where order = orderOrd instance Order Word32 where order = orderOrd instance Order Word64 where order = orderOrd instance Order () where order _ _ = Just EQ _ <~ _ = True comparable _ _ = True instance (Order a, Order b) => Order (a, b) where (a,b) <~ (i,j) = a <~ i && b <~ j instance (Order a, Order b, Order c) => Order (a, b, c) where (a,b,c) <~ (i,j,k) = a <~ i && b <~ j && c <~ k instance (Order a, Order b, Order c, Order d) => Order (a, b, c, d) where (a,b,c,d) <~ (i,j,k,l) = a <~ i && b <~ j && c <~ k && d <~ l instance (Order a, Order b, Order c, Order d, Order e) => Order (a, b, c, d, e) where (a,b,c,d,e) <~ (i,j,k,l,m) = a <~ i && b <~ j && c <~ k && d <~ l && e <~ m