{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
module GHC.TypeLits.Compare
(
(:<=?)(..)
, (%<=?)
, isLE
, isNLE
, SCmpNat(..)
, GHC.TypeLits.Compare.cmpNat
, flipCmpNat
, cmpNatEq
, eqCmpNat
, reflCmpNat
, cmpNatLE
, cmpNatGOrdering
)
where
import Data.Kind
import Data.Type.Equality
import GHC.TypeLits ( Nat, KnownNat, CmpNat
, type (<=?)
, natVal )
import Unsafe.Coerce
import Data.GADT.Compare
isLE
:: (KnownNat m, KnownNat n)
=> p m
-> q n
-> Maybe ((m <=? n) :~: 'True)
isLE :: forall (m :: Nat) (n :: Nat) (p :: Nat -> *) (q :: Nat -> *).
(KnownNat m, KnownNat n) =>
p m -> q n -> Maybe ((m <=? n) :~: 'True)
isLE p m
m q n
n = case p m
m forall (m :: Nat) (n :: Nat) (p :: Nat -> *) (q :: Nat -> *).
(KnownNat m, KnownNat n) =>
p m -> q n -> m :<=? n
%<=? q n
n of
LE (m <=? n) :~: 'True
Refl -> forall a. a -> Maybe a
Just forall {k} (a :: k). a :~: a
Refl
NLE (m <=? n) :~: 'False
_ (n <=? m) :~: 'True
_ -> forall a. Maybe a
Nothing
isNLE
:: (KnownNat m, KnownNat n)
=> p m
-> q n
-> Maybe ((m <=? n) :~: 'False)
isNLE :: forall (m :: Nat) (n :: Nat) (p :: Nat -> *) (q :: Nat -> *).
(KnownNat m, KnownNat n) =>
p m -> q n -> Maybe ((m <=? n) :~: 'False)
isNLE p m
m q n
n = case p m
m forall (m :: Nat) (n :: Nat) (p :: Nat -> *) (q :: Nat -> *).
(KnownNat m, KnownNat n) =>
p m -> q n -> m :<=? n
%<=? q n
n of
NLE (m <=? n) :~: 'False
Refl (n <=? m) :~: 'True
Refl -> forall a. a -> Maybe a
Just forall {k} (a :: k). a :~: a
Refl
LE (m <=? n) :~: 'True
_ -> forall a. Maybe a
Nothing
data (:<=?) :: Nat -> Nat -> Type where
LE :: ((m <=? n) :~: 'True) -> (m :<=? n)
NLE :: ((m <=? n) :~: 'False) -> ((n <=? m) :~: 'True) -> (m :<=? n)
(%<=?)
:: (KnownNat m, KnownNat n)
=> p m
-> q n
-> (m :<=? n)
p m
m %<=? :: forall (m :: Nat) (n :: Nat) (p :: Nat -> *) (q :: Nat -> *).
(KnownNat m, KnownNat n) =>
p m -> q n -> m :<=? n
%<=? q n
n | forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal p m
m forall a. Ord a => a -> a -> Bool
<= forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal q n
n = forall (m :: Nat) (n :: Nat). ((m <=? n) :~: 'True) -> m :<=? n
LE (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
| Bool
otherwise = forall (m :: Nat) (n :: Nat).
((m <=? n) :~: 'False) -> ((n <=? m) :~: 'True) -> m :<=? n
NLE (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl) (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
data SCmpNat :: Nat -> Nat -> Type where
CLT :: (CmpNat m n :~: 'LT) -> SCmpNat m n
CEQ :: (CmpNat m n :~: 'EQ) -> (m :~: n) -> SCmpNat m n
CGT :: (CmpNat m n :~: 'GT) -> SCmpNat m n
cmpNat
:: (KnownNat m, KnownNat n)
=> p m
-> q n
-> SCmpNat m n
cmpNat :: forall (m :: Nat) (n :: Nat) (p :: Nat -> *) (q :: Nat -> *).
(KnownNat m, KnownNat n) =>
p m -> q n -> SCmpNat m n
cmpNat p m
m q n
n = case forall a. Ord a => a -> a -> Ordering
compare (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal p m
m) (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal q n
n) of
Ordering
LT -> forall (m :: Nat) (n :: Nat). (CmpNat m n :~: 'LT) -> SCmpNat m n
CLT (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
Ordering
EQ -> forall (m :: Nat) (n :: Nat).
(CmpNat m n :~: 'EQ) -> (m :~: n) -> SCmpNat m n
CEQ (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl) (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
Ordering
GT -> forall (m :: Nat) (n :: Nat). (CmpNat m n :~: 'GT) -> SCmpNat m n
CGT (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
flipCmpNat :: SCmpNat m n -> SCmpNat n m
flipCmpNat :: forall (m :: Nat) (n :: Nat). SCmpNat m n -> SCmpNat n m
flipCmpNat = \case CLT CmpNat m n :~: 'LT
Refl -> forall (m :: Nat) (n :: Nat). (CmpNat m n :~: 'GT) -> SCmpNat m n
CGT (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
CEQ CmpNat m n :~: 'EQ
Refl m :~: n
Refl -> forall (m :: Nat) (n :: Nat).
(CmpNat m n :~: 'EQ) -> (m :~: n) -> SCmpNat m n
CEQ (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl) forall {k} (a :: k). a :~: a
Refl
CGT CmpNat m n :~: 'GT
Refl -> forall (m :: Nat) (n :: Nat). (CmpNat m n :~: 'LT) -> SCmpNat m n
CLT (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
cmpNatEq :: (CmpNat m n :~: 'EQ) -> (m :~: n)
cmpNatEq :: forall (m :: Nat) (n :: Nat). (CmpNat m n :~: 'EQ) -> m :~: n
cmpNatEq = \case CmpNat m n :~: 'EQ
Refl -> forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl
eqCmpNat :: (m :~: n) -> (CmpNat m n :~: 'EQ)
eqCmpNat :: forall (m :: Nat) (n :: Nat). (m :~: n) -> CmpNat m n :~: 'EQ
eqCmpNat = \case m :~: n
Refl -> forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl
reflCmpNat :: (m :~: n) -> SCmpNat m n
reflCmpNat :: forall (m :: Nat) (n :: Nat). (m :~: n) -> SCmpNat m n
reflCmpNat m :~: n
r = forall (m :: Nat) (n :: Nat).
(CmpNat m n :~: 'EQ) -> (m :~: n) -> SCmpNat m n
CEQ (forall (m :: Nat) (n :: Nat). (m :~: n) -> CmpNat m n :~: 'EQ
eqCmpNat m :~: n
r) m :~: n
r
cmpNatLE :: SCmpNat m n -> (m :<=? n)
cmpNatLE :: forall (m :: Nat) (n :: Nat). SCmpNat m n -> m :<=? n
cmpNatLE = \case CLT CmpNat m n :~: 'LT
Refl -> forall (m :: Nat) (n :: Nat). ((m <=? n) :~: 'True) -> m :<=? n
LE (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
CEQ CmpNat m n :~: 'EQ
Refl m :~: n
Refl -> forall (m :: Nat) (n :: Nat). ((m <=? n) :~: 'True) -> m :<=? n
LE (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
CGT CmpNat m n :~: 'GT
Refl -> forall (m :: Nat) (n :: Nat).
((m <=? n) :~: 'False) -> ((n <=? m) :~: 'True) -> m :<=? n
NLE (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl) (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
cmpNatGOrdering :: SCmpNat n m -> GOrdering n m
cmpNatGOrdering :: forall (n :: Nat) (m :: Nat). SCmpNat n m -> GOrdering n m
cmpNatGOrdering = \case
CLT CmpNat n m :~: 'LT
Refl -> forall {k} (a :: k) (b :: k). GOrdering a b
GLT
CEQ CmpNat n m :~: 'EQ
Refl n :~: m
Refl -> forall {k} (a :: k). GOrdering a a
GEQ
CGT CmpNat n m :~: 'GT
Refl -> forall {k} (a :: k) (b :: k). GOrdering a b
GGT