{-# LANGUAGE
DataKinds,
PolyKinds,
TypeFamilies,
TypeInType,
TypeOperators,
UndecidableInstances #-}
module Fcf.Class.Ord
(
Compare
, type (<=)
, type (>=)
, type (<)
, type (>)
, TyEq
) where
import qualified GHC.TypeLits as TL
import Fcf.Core
import Fcf.Class.Monoid (type (<>))
import Fcf.Data.Bool (Not)
import Fcf.Utils (TyEq)
data Compare :: a -> a -> Exp Ordering
type instance Eval (Compare '(a1, a2) '(b1, b2)) = Eval (Compare a1 b1) <> Eval (Compare a2 b2)
type instance Eval (Compare '(a1, a2, a3) '(b1, b2, b3))
= Eval (Compare a1 b1) <> Eval (Compare a2 b2) <> Eval (Compare a3 b3)
type instance Eval (Compare ('Left a) ('Left b)) = Eval (Compare a b)
type instance Eval (Compare ('Right a) ('Right b)) = Eval (Compare a b)
type instance Eval (Compare ('Left _a) ('Right _b)) = 'LT
type instance Eval (Compare ('Right _a) ('Left _b)) = 'GT
type instance Eval (Compare 'Nothing 'Nothing) = 'EQ
type instance Eval (Compare ('Just a) ('Just b)) = Eval (Compare a b)
type instance Eval (Compare 'Nothing ('Just _b)) = 'LT
type instance Eval (Compare ('Just _a) 'Nothing) = 'GT
type instance Eval (Compare '[] '[]) = 'EQ
type instance Eval (Compare (x ': xs) (y ': ys)) = Eval (Compare x y) <> Eval (Compare xs ys)
type instance Eval (Compare '[] (_y ': _ys)) = 'LT
type instance Eval (Compare (_x ': _xs) '[]) = 'GT
type instance Eval (Compare (a :: Bool) a) = 'EQ
type instance Eval (Compare 'False 'True) = 'GT
type instance Eval (Compare 'True 'False) = 'GT
type instance Eval (Compare (a :: Ordering) a) = 'EQ
type instance Eval (Compare 'LT 'EQ) = 'LT
type instance Eval (Compare 'LT 'GT) = 'LT
type instance Eval (Compare 'EQ 'GT) = 'LT
type instance Eval (Compare 'EQ 'LT) = 'GT
type instance Eval (Compare 'GT 'LT) = 'GT
type instance Eval (Compare 'GT 'EQ) = 'GT
type instance Eval (Compare a b) = TL.CmpSymbol a b
type instance Eval (Compare a b) = TL.CmpNat a b
type instance Eval (Compare (a :: ()) b) = 'EQ
type a ~== b = Eval (TyEq (Eval a) b)
type a ~/= b = Eval (Not (a ~== b))
data (<=) :: a -> a -> Exp Bool
type instance Eval ((<=) a b) = Compare a b ~/= 'GT
data (>=) :: a -> a -> Exp Bool
type instance Eval ((>=) a b) = Compare a b ~/= 'LT
data (<) :: a -> a -> Exp Bool
type instance Eval ((<) a b) = Compare a b ~== 'LT
data (>) :: a -> a -> Exp Bool
type instance Eval ((>) a b) = Compare a b ~== 'GT