{-# LANGUAGE CPP                  #-}
{-# LANGUAGE DataKinds            #-}
{-# LANGUAGE DeriveDataTypeable   #-}
{-# LANGUAGE DeriveGeneric        #-}
{-# LANGUAGE FlexibleContexts     #-}
{-# LANGUAGE PolyKinds            #-}
{-# LANGUAGE UndecidableInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Numeric.ProductOrd
-- Copyright   :  (c) Artem Chirkin
-- License     :  BSD3
--
--
-- Compare product types -- partial order.
--
-----------------------------------------------------------------------------
module Numeric.ProductOrd (ProductOrder (..), PartialOrdering (..), fromOrdering) where


import Data.Data
import Data.Kind      (Type)
import Data.Monoid    as Mon (Monoid (..))
import Data.Semigroup as Sem (Semigroup (..), stimesIdempotentMonoid)
import GHC.Generics

import Numeric.TypedList

-- | Partial order for comparing product types --
--     [product order](https://en.wikipedia.org/wiki/Product_order).
class ProductOrder a where
    -- | Same as `compare`, but may return @Incomparable@.
    cmp :: a -> a -> PartialOrdering

-- | Similar to `Ordering`, but may be @Incomparable@.
data PartialOrdering = PLT | PEQ | PGT | Incomparable
  deriving ( PartialOrdering -> PartialOrdering -> Bool
(PartialOrdering -> PartialOrdering -> Bool)
-> (PartialOrdering -> PartialOrdering -> Bool)
-> Eq PartialOrdering
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PartialOrdering -> PartialOrdering -> Bool
$c/= :: PartialOrdering -> PartialOrdering -> Bool
== :: PartialOrdering -> PartialOrdering -> Bool
$c== :: PartialOrdering -> PartialOrdering -> Bool
Eq, Eq PartialOrdering
Eq PartialOrdering
-> (PartialOrdering -> PartialOrdering -> Ordering)
-> (PartialOrdering -> PartialOrdering -> Bool)
-> (PartialOrdering -> PartialOrdering -> Bool)
-> (PartialOrdering -> PartialOrdering -> Bool)
-> (PartialOrdering -> PartialOrdering -> Bool)
-> (PartialOrdering -> PartialOrdering -> PartialOrdering)
-> (PartialOrdering -> PartialOrdering -> PartialOrdering)
-> Ord PartialOrdering
PartialOrdering -> PartialOrdering -> Bool
PartialOrdering -> PartialOrdering -> Ordering
PartialOrdering -> PartialOrdering -> PartialOrdering
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
min :: PartialOrdering -> PartialOrdering -> PartialOrdering
$cmin :: PartialOrdering -> PartialOrdering -> PartialOrdering
max :: PartialOrdering -> PartialOrdering -> PartialOrdering
$cmax :: PartialOrdering -> PartialOrdering -> PartialOrdering
>= :: PartialOrdering -> PartialOrdering -> Bool
$c>= :: PartialOrdering -> PartialOrdering -> Bool
> :: PartialOrdering -> PartialOrdering -> Bool
$c> :: PartialOrdering -> PartialOrdering -> Bool
<= :: PartialOrdering -> PartialOrdering -> Bool
$c<= :: PartialOrdering -> PartialOrdering -> Bool
< :: PartialOrdering -> PartialOrdering -> Bool
$c< :: PartialOrdering -> PartialOrdering -> Bool
compare :: PartialOrdering -> PartialOrdering -> Ordering
$ccompare :: PartialOrdering -> PartialOrdering -> Ordering
$cp1Ord :: Eq PartialOrdering
Ord, Int -> PartialOrdering -> ShowS
[PartialOrdering] -> ShowS
PartialOrdering -> String
(Int -> PartialOrdering -> ShowS)
-> (PartialOrdering -> String)
-> ([PartialOrdering] -> ShowS)
-> Show PartialOrdering
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PartialOrdering] -> ShowS
$cshowList :: [PartialOrdering] -> ShowS
show :: PartialOrdering -> String
$cshow :: PartialOrdering -> String
showsPrec :: Int -> PartialOrdering -> ShowS
$cshowsPrec :: Int -> PartialOrdering -> ShowS
Show, ReadPrec [PartialOrdering]
ReadPrec PartialOrdering
Int -> ReadS PartialOrdering
ReadS [PartialOrdering]
(Int -> ReadS PartialOrdering)
-> ReadS [PartialOrdering]
-> ReadPrec PartialOrdering
-> ReadPrec [PartialOrdering]
-> Read PartialOrdering
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PartialOrdering]
$creadListPrec :: ReadPrec [PartialOrdering]
readPrec :: ReadPrec PartialOrdering
$creadPrec :: ReadPrec PartialOrdering
readList :: ReadS [PartialOrdering]
$creadList :: ReadS [PartialOrdering]
readsPrec :: Int -> ReadS PartialOrdering
$creadsPrec :: Int -> ReadS PartialOrdering
Read, Typeable PartialOrdering
DataType
Constr
Typeable PartialOrdering
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PartialOrdering -> c PartialOrdering)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PartialOrdering)
-> (PartialOrdering -> Constr)
-> (PartialOrdering -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PartialOrdering))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c PartialOrdering))
-> ((forall b. Data b => b -> b)
    -> PartialOrdering -> PartialOrdering)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> PartialOrdering -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> PartialOrdering -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> PartialOrdering -> m PartialOrdering)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> PartialOrdering -> m PartialOrdering)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> PartialOrdering -> m PartialOrdering)
-> Data PartialOrdering
PartialOrdering -> DataType
PartialOrdering -> Constr
(forall b. Data b => b -> b) -> PartialOrdering -> PartialOrdering
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PartialOrdering -> c PartialOrdering
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PartialOrdering
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> PartialOrdering -> u
forall u. (forall d. Data d => d -> u) -> PartialOrdering -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PartialOrdering
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PartialOrdering -> c PartialOrdering
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PartialOrdering)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c PartialOrdering)
$cIncomparable :: Constr
$cPGT :: Constr
$cPEQ :: Constr
$cPLT :: Constr
$tPartialOrdering :: DataType
gmapMo :: (forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
gmapMp :: (forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
gmapM :: (forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> PartialOrdering -> m PartialOrdering
gmapQi :: Int -> (forall d. Data d => d -> u) -> PartialOrdering -> u
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> PartialOrdering -> u
gmapQ :: (forall d. Data d => d -> u) -> PartialOrdering -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> PartialOrdering -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PartialOrdering -> r
gmapT :: (forall b. Data b => b -> b) -> PartialOrdering -> PartialOrdering
$cgmapT :: (forall b. Data b => b -> b) -> PartialOrdering -> PartialOrdering
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c PartialOrdering)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c PartialOrdering)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c PartialOrdering)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PartialOrdering)
dataTypeOf :: PartialOrdering -> DataType
$cdataTypeOf :: PartialOrdering -> DataType
toConstr :: PartialOrdering -> Constr
$ctoConstr :: PartialOrdering -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PartialOrdering
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PartialOrdering
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PartialOrdering -> c PartialOrdering
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PartialOrdering -> c PartialOrdering
$cp1Data :: Typeable PartialOrdering
Data, Typeable, (forall x. PartialOrdering -> Rep PartialOrdering x)
-> (forall x. Rep PartialOrdering x -> PartialOrdering)
-> Generic PartialOrdering
forall x. Rep PartialOrdering x -> PartialOrdering
forall x. PartialOrdering -> Rep PartialOrdering x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PartialOrdering x -> PartialOrdering
$cfrom :: forall x. PartialOrdering -> Rep PartialOrdering x
Generic, Int -> PartialOrdering
PartialOrdering -> Int
PartialOrdering -> [PartialOrdering]
PartialOrdering -> PartialOrdering
PartialOrdering -> PartialOrdering -> [PartialOrdering]
PartialOrdering
-> PartialOrdering -> PartialOrdering -> [PartialOrdering]
(PartialOrdering -> PartialOrdering)
-> (PartialOrdering -> PartialOrdering)
-> (Int -> PartialOrdering)
-> (PartialOrdering -> Int)
-> (PartialOrdering -> [PartialOrdering])
-> (PartialOrdering -> PartialOrdering -> [PartialOrdering])
-> (PartialOrdering -> PartialOrdering -> [PartialOrdering])
-> (PartialOrdering
    -> PartialOrdering -> PartialOrdering -> [PartialOrdering])
-> Enum PartialOrdering
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PartialOrdering
-> PartialOrdering -> PartialOrdering -> [PartialOrdering]
$cenumFromThenTo :: PartialOrdering
-> PartialOrdering -> PartialOrdering -> [PartialOrdering]
enumFromTo :: PartialOrdering -> PartialOrdering -> [PartialOrdering]
$cenumFromTo :: PartialOrdering -> PartialOrdering -> [PartialOrdering]
enumFromThen :: PartialOrdering -> PartialOrdering -> [PartialOrdering]
$cenumFromThen :: PartialOrdering -> PartialOrdering -> [PartialOrdering]
enumFrom :: PartialOrdering -> [PartialOrdering]
$cenumFrom :: PartialOrdering -> [PartialOrdering]
fromEnum :: PartialOrdering -> Int
$cfromEnum :: PartialOrdering -> Int
toEnum :: Int -> PartialOrdering
$ctoEnum :: Int -> PartialOrdering
pred :: PartialOrdering -> PartialOrdering
$cpred :: PartialOrdering -> PartialOrdering
succ :: PartialOrdering -> PartialOrdering
$csucc :: PartialOrdering -> PartialOrdering
Enum, PartialOrdering
PartialOrdering -> PartialOrdering -> Bounded PartialOrdering
forall a. a -> a -> Bounded a
maxBound :: PartialOrdering
$cmaxBound :: PartialOrdering
minBound :: PartialOrdering
$cminBound :: PartialOrdering
Bounded )

-- | Extend `Ordering` with @Incomparable@ option.
fromOrdering :: Ordering -> PartialOrdering
fromOrdering :: Ordering -> PartialOrdering
fromOrdering Ordering
LT = PartialOrdering
PLT
fromOrdering Ordering
EQ = PartialOrdering
PEQ
fromOrdering Ordering
GT = PartialOrdering
PGT
{-# INLINE fromOrdering #-}

instance Sem.Semigroup PartialOrdering where
    PartialOrdering
Incomparable <> :: PartialOrdering -> PartialOrdering -> PartialOrdering
<> PartialOrdering
_ = PartialOrdering
Incomparable
    PartialOrdering
_ <> PartialOrdering
Incomparable = PartialOrdering
Incomparable
    PartialOrdering
PLT <> PartialOrdering
PGT = PartialOrdering
Incomparable
    PartialOrdering
PGT <> PartialOrdering
PLT = PartialOrdering
Incomparable
    PartialOrdering
PLT <> PartialOrdering
_ = PartialOrdering
PLT
    PartialOrdering
PGT <> PartialOrdering
_ = PartialOrdering
PGT
    PartialOrdering
PEQ <> PartialOrdering
y = PartialOrdering
y

    stimes :: b -> PartialOrdering -> PartialOrdering
stimes = b -> PartialOrdering -> PartialOrdering
forall b a. (Integral b, Monoid a) => b -> a -> a
stimesIdempotentMonoid

instance Mon.Monoid PartialOrdering where
    mempty :: PartialOrdering
mempty = PartialOrdering
PEQ
#if !(MIN_VERSION_base(4,11,0))
    mappend = (<>)
#endif

instance All Ord (Map f xs)
      => ProductOrder (TypedList (f :: k -> Type) (xs :: [k])) where
    cmp :: TypedList f xs -> TypedList f xs -> PartialOrdering
cmp TypedList f xs
U TypedList f xs
U                 = PartialOrdering
PEQ
    cmp (f y
a :* TypedList f ys
as) (f y
b :* TypedList f ys
bs) = Ordering -> PartialOrdering
fromOrdering (f y -> f y -> Ordering
forall a. Ord a => a -> a -> Ordering
compare f y
a f y
f y
b) PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> TypedList f ys -> TypedList f ys -> PartialOrdering
forall a. ProductOrder a => a -> a -> PartialOrdering
cmp TypedList f ys
as TypedList f ys
TypedList f ys
bs


cmp' :: Ord a => a -> a -> PartialOrdering
cmp' :: a -> a -> PartialOrdering
cmp' a
a a
b = Ordering -> PartialOrdering
fromOrdering (a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
a a
b)
{-# INLINE cmp' #-}

instance (Ord a1, Ord a2)
      => ProductOrder (a1, a2) where
    cmp :: (a1, a2) -> (a1, a2) -> PartialOrdering
cmp (a1
a1, a2
a2)
        (a1
b1, a2
b2)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2

instance (Ord a1, Ord a2, Ord a3)
      => ProductOrder (a1, a2, a3) where
    cmp :: (a1, a2, a3) -> (a1, a2, a3) -> PartialOrdering
cmp (a1
a1, a2
a2, a3
a3)
        (a1
b1, a2
b2, a3
b3)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a3 -> a3 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a3
a3 a3
b3

instance (Ord a1, Ord a2, Ord a3, Ord a4)
      => ProductOrder (a1, a2, a3, a4) where
    cmp :: (a1, a2, a3, a4) -> (a1, a2, a3, a4) -> PartialOrdering
cmp (a1
a1, a2
a2, a3
a3, a4
a4)
        (a1
b1, a2
b2, a3
b3, a4
b4)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a3 -> a3 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a3
a3 a3
b3
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a4 -> a4 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a4
a4 a4
b4

instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5)
      => ProductOrder (a1, a2, a3, a4, a5) where
    cmp :: (a1, a2, a3, a4, a5) -> (a1, a2, a3, a4, a5) -> PartialOrdering
cmp (a1
a1, a2
a2, a3
a3, a4
a4, a5
a5)
        (a1
b1, a2
b2, a3
b3, a4
b4, a5
b5)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a3 -> a3 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a3
a3 a3
b3
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a4 -> a4 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a4
a4 a4
b4 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a5 -> a5 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a5
a5 a5
b5

instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6)
      => ProductOrder (a1, a2, a3, a4, a5, a6) where
    cmp :: (a1, a2, a3, a4, a5, a6)
-> (a1, a2, a3, a4, a5, a6) -> PartialOrdering
cmp (a1
a1, a2
a2, a3
a3, a4
a4, a5
a5, a6
a6)
        (a1
b1, a2
b2, a3
b3, a4
b4, a5
b5, a6
b6)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a3 -> a3 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a3
a3 a3
b3
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a4 -> a4 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a4
a4 a4
b4 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a5 -> a5 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a5
a5 a5
b5 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a6 -> a6 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a6
a6 a6
b6

instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7)
      => ProductOrder (a1, a2, a3, a4, a5, a6, a7) where
    cmp :: (a1, a2, a3, a4, a5, a6, a7)
-> (a1, a2, a3, a4, a5, a6, a7) -> PartialOrdering
cmp (a1
a1, a2
a2, a3
a3, a4
a4, a5
a5, a6
a6, a7
a7)
        (a1
b1, a2
b2, a3
b3, a4
b4, a5
b5, a6
b6, a7
b7)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a3 -> a3 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a3
a3 a3
b3
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a4 -> a4 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a4
a4 a4
b4 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a5 -> a5 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a5
a5 a5
b5 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a6 -> a6 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a6
a6 a6
b6
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a7 -> a7 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a7
a7 a7
b7

instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8)
      => ProductOrder (a1, a2, a3, a4, a5, a6, a7, a8) where
    cmp :: (a1, a2, a3, a4, a5, a6, a7, a8)
-> (a1, a2, a3, a4, a5, a6, a7, a8) -> PartialOrdering
cmp (a1
a1, a2
a2, a3
a3, a4
a4, a5
a5, a6
a6, a7
a7, a8
a8)
        (a1
b1, a2
b2, a3
b3, a4
b4, a5
b5, a6
b6, a7
b7, a8
b8)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a3 -> a3 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a3
a3 a3
b3
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a4 -> a4 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a4
a4 a4
b4 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a5 -> a5 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a5
a5 a5
b5 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a6 -> a6 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a6
a6 a6
b6
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a7 -> a7 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a7
a7 a7
b7 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a8 -> a8 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a8
a8 a8
b8

instance (Ord a1, Ord a2, Ord a3, Ord a4, Ord a5, Ord a6, Ord a7, Ord a8, Ord a9)
      => ProductOrder (a1, a2, a3, a4, a5, a6, a7, a8, a9) where
    cmp :: (a1, a2, a3, a4, a5, a6, a7, a8, a9)
-> (a1, a2, a3, a4, a5, a6, a7, a8, a9) -> PartialOrdering
cmp (a1
a1, a2
a2, a3
a3, a4
a4, a5
a5, a6
a6, a7
a7, a8
a8, a9
a9)
        (a1
b1, a2
b2, a3
b3, a4
b4, a5
b5, a6
b6, a7
b7, a8
b8, a9
b9)
      =  a1 -> a1 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a1
a1 a1
b1 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a2 -> a2 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a2
a2 a2
b2 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a3 -> a3 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a3
a3 a3
b3
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a4 -> a4 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a4
a4 a4
b4 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a5 -> a5 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a5
a5 a5
b5 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a6 -> a6 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a6
a6 a6
b6
      PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a7 -> a7 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a7
a7 a7
b7 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a8 -> a8 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a8
a8 a8
b8 PartialOrdering -> PartialOrdering -> PartialOrdering
forall a. Semigroup a => a -> a -> a
<> a9 -> a9 -> PartialOrdering
forall a. Ord a => a -> a -> PartialOrdering
cmp' a9
a9 a9
b9