{-# LANGUAGE GHC2024, TemplateHaskell, DerivingStrategies #-} module INTx where import GHC.TypeLits (Nat, KnownNat) import qualified Language.Haskell.TH as TH -- | ABI integer value types, where @s@ is for signess and @n@ is the multiple of 8 bits newtype INTx (s :: Bool) (n :: Nat) = INT Integer deriving newtype (Eq, Ord, Enum) -- | A constraint that restricts what Nat values are valid for 'INTx'. class KnownNat n => ValidINTn n -- | A top-level splice that declares all the valid INTx n values. flip foldMap [1..32] $ \i -> [d| instance ValidINTn $(TH.litT (TH.numTyLit i)) |] -- | Sign of the INTx type. Use type application on @a@. intxSign :: forall a (s :: Bool) (n :: Nat). (a ~ INTx s n, KnownBool s, ValidINTn n) => Bool intxSign = toBool (SBool @s) -- | Number of bits for the INTx type. Use type application on @a@. intxNBits :: forall a (s :: Bool) (n :: Nat). (a ~ INTx s n, ValidINTn n) => Int intxNBits = fromEnum (8 * natVal (Proxy @n))