{-# LANGUAGE DataKinds, TypeApplications#-} import GHC.TypeLits (KnownNat, natVal) import Data.Proxy (Proxy (..)) newtype Mod n = Mod Integer deriving (Eq, Ord) instance (KnownNat n) => Num (Mod n) where fromInteger i = Mod $ i `mod` natVal (Proxy @n) (Mod a) + (Mod b) = Mod $ (a + b) `mod` natVal (Proxy @n) (Mod a) * (Mod b) = Mod $ (a * b) `mod` natVal (Proxy @n) (Mod a) - (Mod b) = Mod $ (a - b) `mod` natVal (Proxy @n) abs = id signum = id instance (KnownNat n) => Show (Mod n) where show (Mod i) = show i <> " (mod " <> show (natVal $ Proxy @n) <> ")"