{-# LANGUAGE GHC2024 #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE QuasiQuotes #-} -- base import GHC.TypeLits (SNat, KnownNat (natSing), natVal, withSomeSNat, fromSNat) -- template-haskell import qualified Language.Haskell.TH as TH class KnownNat n => ValidUINTn n data UINTn where UINTn :: ValidUINTn n => SNat n -> UINTn flip foldMap [1..32] $ \i -> [d| instance ValidUINTn $(TH.litT (TH.numTyLit i)) |] instance Show UINTn where show (UINTn sn) = "UINT" <> show (natVal sn * 8) getValidUINTn :: Integer -> Maybe UINTn getValidUINTn x = withSomeSNat x $ \maybeSn -> maybeSn >>= \sn -> let n = fromSNat sn in $(TH.caseE (TH.varE 'n) (map (\i -> TH.match (TH.litP (TH.integerL i)) (TH.normalB ( TH.conE 'Just `TH.appE` ((TH.conE 'UINTn) `TH.appE` (TH.varE 'natSing `TH.appTypeE` TH.litT (TH.numTyLit i))))) [] ) [1..32] ++ [ TH.match TH.wildP (TH.normalB (TH.conE 'Nothing)) [] ] ) ) main = do print $ UINTn (natSing @2) print $ getValidUINTn 4 print $ getValidUINTn 32 print $ getValidUINTn 33