{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE NoStarIsType #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}
module GHC.TypeLits.Witnesses (
SNat(..)
, SomeNat(SomeNat_)
, Natural(FromSNat)
, fromSNat
, withKnownNat
, withSomeNat
, toSomeNat
, (%+)
, (%-)
, minusSNat
, minusSNat_
, (%*)
, (%^)
, (%<=?)
, sCmpNat
, unsafeLiftNatOp1
, unsafeLiftNatOp2
, SSymbol(..)
, SomeSymbol(SomeSymbol_)
, pattern FromSSymbol
, fromSSymbol
, withKnownSymbol
, withSomeSymbol
, toSomeSymbol
) where
import Data.GADT.Compare
import Data.GADT.Show
import Data.Proxy
import Data.Type.Equality
import GHC.Natural
import GHC.TypeLits ( KnownSymbol, SomeSymbol(..)
, symbolVal, someSymbolVal, sameSymbol )
import GHC.TypeLits.Compare hiding ((%<=?))
import GHC.TypeNats ( KnownNat, SomeNat(..), CmpNat
, type (+), type (-), type (*), type (^)
, natVal, someNatVal, sameNat )
import Unsafe.Coerce
import qualified GHC.TypeLits.Compare as Comp
data SNat n = KnownNat n => SNat
deriving instance Eq (SNat n)
deriving instance Ord (SNat n)
instance Show (SNat n) where
showsPrec :: Int -> SNat n -> ShowS
showsPrec Int
d x :: SNat n
x@SNat n
SNat = Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"SNat @" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 (forall (n :: Nat). SNat n -> Nat
fromSNat SNat n
x)
instance GShow SNat where
gshowsPrec :: forall (n :: Nat). Int -> SNat n -> ShowS
gshowsPrec = forall a. Show a => Int -> a -> ShowS
showsPrec
instance TestEquality SNat where
testEquality :: forall (a :: Nat) (b :: Nat). SNat a -> SNat b -> Maybe (a :~: b)
testEquality (SNat a
SNat :: SNat n) (SNat b
SNat :: SNat m) =
forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (a :: Nat) (b :: Nat) (proxy1 :: Nat -> Type)
(proxy2 :: Nat -> Type).
(KnownNat a, KnownNat b) =>
proxy1 a -> proxy2 b -> Maybe (a :~: b)
sameNat (forall {k} (t :: k). Proxy t
Proxy :: Proxy n) (forall {k} (t :: k). Proxy t
Proxy :: Proxy m)) forall a b. (a -> b) -> a -> b
$ \case
a :~: b
Refl -> forall {k} (a :: k). a :~: a
Refl
instance GEq SNat where
geq :: forall (a :: Nat) (b :: Nat). SNat a -> SNat b -> Maybe (a :~: b)
geq = forall {k} (f :: k -> Type) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality
instance GCompare SNat where
gcompare :: forall (a :: Nat) (b :: Nat). SNat a -> SNat b -> GOrdering a b
gcompare SNat a
x = forall (n :: Nat) (m :: Nat). SCmpNat n m -> GOrdering n m
cmpNatGOrdering forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> SCmpNat n m
sCmpNat SNat a
x
data SomeNat__ = forall n. SomeNat__ (SNat n)
pattern SomeNat_ :: SNat n -> SomeNat
pattern $bSomeNat_ :: forall (n :: Nat). SNat n -> SomeNat
$mSomeNat_ :: forall {r}.
SomeNat -> (forall {n :: Nat}. SNat n -> r) -> ((# #) -> r) -> r
SomeNat_ x <- ((\case SomeNat (Proxy n
Proxy :: Proxy n) -> forall (n :: Nat). SNat n -> SomeNat__
SomeNat__ (forall (n :: Nat). KnownNat n => SNat n
SNat :: SNat n)) -> SomeNat__ x)
where
SomeNat_ (SNat n
SNat :: SNat n) = forall (n :: Nat). KnownNat n => Proxy n -> SomeNat
SomeNat (forall {k} (t :: k). Proxy t
Proxy :: Proxy n)
{-# COMPLETE SomeNat_ #-}
pattern FromSNat :: SNat n -> Natural
pattern $bFromSNat :: forall (n :: Nat). SNat n -> Nat
$mFromSNat :: forall {r}.
Nat -> (forall {n :: Nat}. SNat n -> r) -> ((# #) -> r) -> r
FromSNat x <- ((\Nat
i -> forall r. Nat -> (forall (n :: Nat). SNat n -> r) -> r
withSomeNat Nat
i forall (n :: Nat). SNat n -> SomeNat
SomeNat_) -> SomeNat_ x)
where
FromSNat = forall (n :: Nat). SNat n -> Nat
fromSNat
{-# COMPLETE FromSNat #-}
withKnownNat :: SNat n -> (KnownNat n => r) -> r
withKnownNat :: forall (n :: Nat) r. SNat n -> (KnownNat n => r) -> r
withKnownNat SNat n
SNat KnownNat n => r
x = KnownNat n => r
x
withSomeNat :: Natural -> (forall n. SNat n -> r) -> r
withSomeNat :: forall r. Nat -> (forall (n :: Nat). SNat n -> r) -> r
withSomeNat (Nat -> SomeNat
someNatVal->SomeNat (Proxy n
Proxy :: Proxy n)) forall (n :: Nat). SNat n -> r
x = forall (n :: Nat). SNat n -> r
x (forall (n :: Nat). KnownNat n => SNat n
SNat :: SNat n)
toSomeNat :: Natural -> SomeNat
toSomeNat :: Nat -> SomeNat
toSomeNat = Nat -> SomeNat
someNatVal
fromSNat :: SNat n -> Natural
fromSNat :: forall (n :: Nat). SNat n -> Nat
fromSNat x :: SNat n
x@SNat n
SNat = forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal SNat n
x
unsafeLiftNatOp1
:: (Natural -> Natural)
-> SNat n
-> SNat m
unsafeLiftNatOp1 :: forall (n :: Nat) (m :: Nat). (Nat -> Nat) -> SNat n -> SNat m
unsafeLiftNatOp1 Nat -> Nat
f SNat n
x = forall r. Nat -> (forall (n :: Nat). SNat n -> r) -> r
withSomeNat (Nat -> Nat
f (forall (n :: Nat). SNat n -> Nat
fromSNat SNat n
x)) forall a b. a -> b
unsafeCoerce
unsafeLiftNatOp2
:: (Natural -> Natural -> Natural)
-> SNat n
-> SNat m
-> SNat o
unsafeLiftNatOp2 :: forall (n :: Nat) (m :: Nat) (o :: Nat).
(Nat -> Nat -> Nat) -> SNat n -> SNat m -> SNat o
unsafeLiftNatOp2 Nat -> Nat -> Nat
f SNat n
x SNat m
y = forall r. Nat -> (forall (n :: Nat). SNat n -> r) -> r
withSomeNat (Nat -> Nat -> Nat
f (forall (n :: Nat). SNat n -> Nat
fromSNat SNat n
x) (forall (n :: Nat). SNat n -> Nat
fromSNat SNat m
y)) forall a b. a -> b
unsafeCoerce
(%+) :: SNat n -> SNat m -> SNat (n + m)
%+ :: forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> SNat (n + m)
(%+) = forall (n :: Nat) (m :: Nat) (o :: Nat).
(Nat -> Nat -> Nat) -> SNat n -> SNat m -> SNat o
unsafeLiftNatOp2 forall a. Num a => a -> a -> a
(+)
(%-) :: SNat n -> SNat m -> SNat (n - m)
%- :: forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> SNat (n - m)
(%-) = forall (n :: Nat) (m :: Nat) (o :: Nat).
(Nat -> Nat -> Nat) -> SNat n -> SNat m -> SNat o
unsafeLiftNatOp2 (-)
minusSNat
:: SNat n
-> SNat m
-> Either (CmpNat n m :~: 'LT) (SNat (n - m))
minusSNat :: forall (n :: Nat) (m :: Nat).
SNat n -> SNat m -> Either (CmpNat n m :~: 'LT) (SNat (n - m))
minusSNat (forall (n :: Nat). SNat n -> Nat
fromSNat->Nat
x) (forall (n :: Nat). SNat n -> Nat
fromSNat->Nat
y) = case Nat -> Nat -> Maybe Nat
minusNaturalMaybe Nat
x Nat
y of
Maybe Nat
Nothing -> forall a b. a -> Either a b
Left (forall a b. a -> b
unsafeCoerce forall {k} (a :: k). a :~: a
Refl)
Just Nat
z -> forall r. Nat -> (forall (n :: Nat). SNat n -> r) -> r
withSomeNat Nat
z (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b
unsafeCoerce)
minusSNat_ :: SNat n -> SNat m -> Maybe (SNat (n - m))
minusSNat_ :: forall (n :: Nat) (m :: Nat).
SNat n -> SNat m -> Maybe (SNat (n - m))
minusSNat_ SNat n
x = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) (m :: Nat).
SNat n -> SNat m -> Either (CmpNat n m :~: 'LT) (SNat (n - m))
minusSNat SNat n
x
(%*) :: SNat n -> SNat m -> SNat (n * m)
%* :: forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> SNat (n * m)
(%*) = forall (n :: Nat) (m :: Nat) (o :: Nat).
(Nat -> Nat -> Nat) -> SNat n -> SNat m -> SNat o
unsafeLiftNatOp2 forall a. Num a => a -> a -> a
(*)
(%^) :: SNat n -> SNat m -> SNat (n ^ m)
%^ :: forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> SNat (n ^ m)
(%^) = forall (n :: Nat) (m :: Nat) (o :: Nat).
(Nat -> Nat -> Nat) -> SNat n -> SNat m -> SNat o
unsafeLiftNatOp2 forall a b. (Num a, Integral b) => a -> b -> a
(^)
(%<=?) :: SNat n -> SNat m -> n :<=? m
x :: SNat n
x@SNat n
SNat %<=? :: forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> n :<=? m
%<=? y :: SNat m
y@SNat m
SNat = SNat n
x forall (m :: Nat) (n :: Nat) (p :: Nat -> Type) (q :: Nat -> Type).
(KnownNat m, KnownNat n) =>
p m -> q n -> m :<=? n
Comp.%<=? SNat m
y
sCmpNat :: SNat n -> SNat m -> SCmpNat n m
sCmpNat :: forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> SCmpNat n m
sCmpNat x :: SNat n
x@SNat n
SNat y :: SNat m
y@SNat m
SNat = forall (m :: Nat) (n :: Nat) (p :: Nat -> Type) (q :: Nat -> Type).
(KnownNat m, KnownNat n) =>
p m -> q n -> SCmpNat m n
GHC.TypeLits.Compare.cmpNat SNat n
x SNat m
y
data SSymbol n = KnownSymbol n => SSymbol
deriving instance Eq (SSymbol n)
deriving instance Ord (SSymbol n)
instance Show (SSymbol n) where
showsPrec :: Int -> SSymbol n -> ShowS
showsPrec Int
d x :: SSymbol n
x@SSymbol n
SSymbol = Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"SSymbol @" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 (forall (n :: Symbol). SSymbol n -> String
fromSSymbol SSymbol n
x)
instance GShow SSymbol where
gshowsPrec :: forall (n :: Symbol). Int -> SSymbol n -> ShowS
gshowsPrec = forall a. Show a => Int -> a -> ShowS
showsPrec
instance TestEquality SSymbol where
testEquality :: forall (a :: Symbol) (b :: Symbol).
SSymbol a -> SSymbol b -> Maybe (a :~: b)
testEquality (SSymbol a
SSymbol :: SSymbol n) (SSymbol b
SSymbol :: SSymbol m) =
forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (a :: Symbol) (b :: Symbol) (proxy1 :: Symbol -> Type)
(proxy2 :: Symbol -> Type).
(KnownSymbol a, KnownSymbol b) =>
proxy1 a -> proxy2 b -> Maybe (a :~: b)
sameSymbol (forall {k} (t :: k). Proxy t
Proxy :: Proxy n) (forall {k} (t :: k). Proxy t
Proxy :: Proxy m)) forall a b. (a -> b) -> a -> b
$ \case
a :~: b
Refl -> forall {k} (a :: k). a :~: a
Refl
instance GEq SSymbol where
geq :: forall (a :: Symbol) (b :: Symbol).
SSymbol a -> SSymbol b -> Maybe (a :~: b)
geq = forall {k} (f :: k -> Type) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality
instance GCompare SSymbol where
gcompare :: forall (a :: Symbol) (b :: Symbol).
SSymbol a -> SSymbol b -> GOrdering a b
gcompare SSymbol a
x SSymbol b
y = case forall a. Ord a => a -> a -> Ordering
compare (forall (n :: Symbol). SSymbol n -> String
fromSSymbol SSymbol a
x) (forall (n :: Symbol). SSymbol n -> String
fromSSymbol SSymbol b
y) of
Ordering
LT -> forall {k} (a :: k) (b :: k). GOrdering a b
GLT
Ordering
EQ -> forall a b. a -> b
unsafeCoerce forall {k} (a :: k). GOrdering a a
GEQ
Ordering
GT -> forall {k} (a :: k) (b :: k). GOrdering a b
GGT
data SomeSymbol__ = forall n. SomeSymbol__ (SSymbol n)
pattern SomeSymbol_ :: SSymbol n -> SomeSymbol
pattern $bSomeSymbol_ :: forall (n :: Symbol). SSymbol n -> SomeSymbol
$mSomeSymbol_ :: forall {r}.
SomeSymbol
-> (forall {n :: Symbol}. SSymbol n -> r) -> ((# #) -> r) -> r
SomeSymbol_ x <- ((\case SomeSymbol (Proxy n
Proxy :: Proxy n) -> forall (n :: Symbol). SSymbol n -> SomeSymbol__
SomeSymbol__ (forall (n :: Symbol). KnownSymbol n => SSymbol n
SSymbol :: SSymbol n)) -> SomeSymbol__ x)
where
SomeSymbol_ (SSymbol n
SSymbol :: SSymbol n) = forall (n :: Symbol). KnownSymbol n => Proxy n -> SomeSymbol
SomeSymbol (forall {k} (t :: k). Proxy t
Proxy :: Proxy n)
{-# COMPLETE SomeSymbol_ #-}
pattern FromSSymbol :: SSymbol n -> String
pattern $bFromSSymbol :: forall (n :: Symbol). SSymbol n -> String
$mFromSSymbol :: forall {r}.
String
-> (forall {n :: Symbol}. SSymbol n -> r) -> ((# #) -> r) -> r
FromSSymbol x <- ((\String
i -> forall r. String -> (forall (n :: Symbol). SSymbol n -> r) -> r
withSomeSymbol String
i forall (n :: Symbol). SSymbol n -> SomeSymbol
SomeSymbol_) -> SomeSymbol_ x)
where
FromSSymbol = forall (n :: Symbol). SSymbol n -> String
fromSSymbol
{-# COMPLETE FromSSymbol #-}
withKnownSymbol :: SSymbol n -> (KnownSymbol n => r) -> r
withKnownSymbol :: forall (n :: Symbol) r. SSymbol n -> (KnownSymbol n => r) -> r
withKnownSymbol SSymbol n
SSymbol KnownSymbol n => r
x = KnownSymbol n => r
x
withSomeSymbol :: String -> (forall n. SSymbol n -> r) -> r
withSomeSymbol :: forall r. String -> (forall (n :: Symbol). SSymbol n -> r) -> r
withSomeSymbol (String -> SomeSymbol
someSymbolVal->SomeSymbol (Proxy n
Proxy :: Proxy n)) forall (n :: Symbol). SSymbol n -> r
x = forall (n :: Symbol). SSymbol n -> r
x (forall (n :: Symbol). KnownSymbol n => SSymbol n
SSymbol :: SSymbol n)
toSomeSymbol :: String -> SomeSymbol
toSomeSymbol :: String -> SomeSymbol
toSomeSymbol = String -> SomeSymbol
someSymbolVal
fromSSymbol :: SSymbol n -> String
fromSSymbol :: forall (n :: Symbol). SSymbol n -> String
fromSSymbol x :: SSymbol n
x@SSymbol n
SSymbol = forall (n :: Symbol) (proxy :: Symbol -> Type).
KnownSymbol n =>
proxy n -> String
symbolVal SSymbol n
x