{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
#if MIN_VERSION_ghc(8,6,0)
{-# LANGUAGE NoStarIsType #-}
#endif
#if !MIN_VERSION_ghc(8,2,0)
{-# LANGUAGE BangPatterns #-}
#endif
{-# LANGUAGE Trustworthy #-}
{-# OPTIONS_GHC -Wno-unused-top-binds -fexpose-all-unfoldings #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module GHC.TypeLits.KnownNat
(
SNatKn (..)
, KnownNat1 (..)
, KnownNat2 (..)
, KnownNat3 (..)
, SBool (..)
, boolVal
, KnownBool (..)
, SBoolKb (..)
, KnownNat2Bool (..)
, KnownBoolNat2 (..)
, nameToSymbol
)
where
import GHC.Natural (shiftLNatural)
import Data.Proxy (Proxy (..))
import Data.Type.Bool (If)
import GHC.Prim (Proxy#)
import GHC.TypeNats
(KnownNat, Nat, type (+), type (*), type (^), type (-), type (<=?), type (<=),
type Mod, type Div, natVal)
import GHC.TypeLits (Symbol)
import Numeric.Natural (Natural)
import Data.Type.Ord (OrdCond)
import GHC.Types (Constraint)
import GHC.TypeLits.KnownNat.TH
newtype SNatKn (f :: Symbol) = SNatKn Natural
class KnownNat1 (f :: Symbol) (a :: Nat) where
natSing1 :: SNatKn f
class KnownNat2 (f :: Symbol) (a :: Nat) (b :: Nat) where
natSing2 :: SNatKn f
class KnownNat3 (f :: Symbol) (a :: Nat) (b :: Nat) (c :: Nat) where
natSing3 :: SNatKn f
instance (KnownNat a, KnownNat b) => KnownNat2 $(nameToSymbol ''(+)) a b where
natSing2 :: SNatKn "GHC.TypeNats.+"
natSing2 = Nat -> SNatKn "GHC.TypeNats.+"
forall (f :: Symbol). Nat -> SNatKn f
SNatKn (Proxy a -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) Nat -> Nat -> Nat
forall a. Num a => a -> a -> a
+ Proxy b -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @b))
{-# NOINLINE natSing2 #-}
instance (KnownNat a, KnownNat b) => KnownNat2 $(nameToSymbol ''(*)) a b where
natSing2 :: SNatKn "GHC.TypeNats.*"
natSing2 = Nat -> SNatKn "GHC.TypeNats.*"
forall (f :: Symbol). Nat -> SNatKn f
SNatKn (Proxy a -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) Nat -> Nat -> Nat
forall a. Num a => a -> a -> a
* Proxy b -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @b))
{-# NOINLINE natSing2 #-}
instance (KnownNat a, KnownNat b) => KnownNat2 $(nameToSymbol ''(^)) a b where
natSing2 :: SNatKn "GHC.TypeNats.^"
natSing2 = let x :: Nat
x = Proxy a -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
y :: Nat
y = Proxy b -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @b)
z :: Nat
z = case Nat
x of
Nat
2 -> Nat -> Int -> Nat
shiftLNatural Nat
1 (Nat -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Nat
y)
Nat
_ -> Nat
x Nat -> Nat -> Nat
forall a b. (Num a, Integral b) => a -> b -> a
^ Nat
y
in Nat -> SNatKn "GHC.TypeNats.^"
forall (f :: Symbol). Nat -> SNatKn f
SNatKn Nat
z
{-# NOINLINE natSing2 #-}
instance (KnownNat a, KnownNat b, (b <= a) ~ (() :: Constraint)) => KnownNat2 $(nameToSymbol ''(-)) a b where
natSing2 :: SNatKn "GHC.TypeNats.-"
natSing2 = Nat -> SNatKn "GHC.TypeNats.-"
forall (f :: Symbol). Nat -> SNatKn f
SNatKn (Proxy a -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) Nat -> Nat -> Nat
forall a. Num a => a -> a -> a
- Proxy b -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @b))
{-# NOINLINE natSing2 #-}
instance (KnownNat x, KnownNat y, (1 <= y) ~ (() :: Constraint)) => KnownNat2 $(nameToSymbol ''Div) x y where
natSing2 :: SNatKn "GHC.TypeNats.Div"
natSing2 = Nat -> SNatKn "GHC.TypeNats.Div"
forall (f :: Symbol). Nat -> SNatKn f
SNatKn (Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
quot (Proxy x -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @x)) (Proxy y -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @y)))
{-# NOINLINE natSing2 #-}
instance (KnownNat x, KnownNat y, (1 <= y) ~ (() :: Constraint)) => KnownNat2 $(nameToSymbol ''Mod) x y where
natSing2 :: SNatKn "GHC.TypeNats.Mod"
natSing2 = Nat -> SNatKn "GHC.TypeNats.Mod"
forall (f :: Symbol). Nat -> SNatKn f
SNatKn (Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
rem (Proxy x -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @x)) (Proxy y -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @y)))
{-# NOINLINE natSing2 #-}
data SBool (b :: Bool) where
SFalse :: SBool 'False
STrue :: SBool 'True
class KnownBool (b :: Bool) where
boolSing :: SBool b
instance KnownBool 'False where
boolSing :: SBool 'False
boolSing = SBool 'False
SFalse
instance KnownBool 'True where
boolSing :: SBool 'True
boolSing = SBool 'True
STrue
boolVal :: forall b proxy . KnownBool b => proxy b -> Bool
boolVal :: forall (b :: Bool) (proxy :: Bool -> Type).
KnownBool b =>
proxy b -> Bool
boolVal proxy b
_ = case SBool b
forall (b :: Bool). KnownBool b => SBool b
boolSing :: SBool b of
SBool b
SFalse -> Bool
False
SBool b
_ -> Bool
True
boolVal' :: forall b . KnownBool b => Proxy# b -> Bool
boolVal' :: forall (b :: Bool). KnownBool b => Proxy# b -> Bool
boolVal' Proxy# b
_ = case SBool b
forall (b :: Bool). KnownBool b => SBool b
boolSing :: SBool b of
SBool b
SFalse -> Bool
False
SBool b
_ -> Bool
True
newtype SBoolKb (f :: Symbol) = SBoolKb Bool
class KnownBoolNat2 (f :: Symbol) (a :: k) (b :: k) where
boolNatSing2 :: SBoolKb f
instance (KnownNat a, KnownNat b) => KnownBoolNat2 $(nameToSymbol ''(<=?)) a b where
boolNatSing2 :: SBoolKb "Data.Type.Ord.<=?"
boolNatSing2 = Bool -> SBoolKb "Data.Type.Ord.<=?"
forall (f :: Symbol). Bool -> SBoolKb f
SBoolKb (Proxy a -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
<= Proxy b -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @b))
{-# NOINLINE boolNatSing2 #-}
instance (KnownNat a, KnownNat b) => KnownBoolNat2 $(nameToSymbol ''OrdCond) a b where
boolNatSing2 :: SBoolKb "Data.Type.Ord.OrdCond"
boolNatSing2 = Bool -> SBoolKb "Data.Type.Ord.OrdCond"
forall (f :: Symbol). Bool -> SBoolKb f
SBoolKb (Proxy a -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
<= Proxy b -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @b))
{-# NOINLINE boolNatSing2 #-}
class KnownNat2Bool (f :: Symbol) (a :: Bool) (b :: k) (c :: k) where
natBoolSing3 :: SNatKn f
instance (KnownBool a, KnownNat b, KnownNat c) => KnownNat2Bool $(nameToSymbol ''If) a b c where
natBoolSing3 :: SNatKn "Data.Type.Bool.If"
natBoolSing3 = Nat -> SNatKn "Data.Type.Bool.If"
forall (f :: Symbol). Nat -> SNatKn f
SNatKn (if Proxy a -> Bool
forall (b :: Bool) (proxy :: Bool -> Type).
KnownBool b =>
proxy b -> Bool
boolVal (forall (t :: Bool). Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) then Proxy b -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @b) else Proxy c -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @c))
{-# NOINLINE natBoolSing3 #-}