 data T a = Cons {
 modulus :: !a
 representative :: !a
 factorPrec :: Int
 (/:) :: C a => a > a > T a
 isCompatible :: Eq a => T a > T a > Bool
 maybeCompatible :: Eq a => T a > T a > Maybe a
 fromRepresentative :: C a => a > a > T a
 lift1 :: Eq a => (a > a > a) > T a > T a
 lift2 :: Eq a => (a > a > a > a) > T a > T a > T a
 errIncompat :: a
 zero :: C a => a > T a
 one :: C a => a > T a
 fromInteger :: C a => a > Integer > T a
Documentation
The best solution seems to let modulus
be part of the type.
This could happen with a phantom type for modulus
and a run
function like Control.Monad.ST.runST
.
Then operations with nonmatching moduli could be detected at compile time
and zero
and one
could be generated with the correct modulus.
An alternative trial can be found in module ResidueClassMaybe.
Cons  

(/:) :: C a => a > a > T aSource
r /: m
is the residue class containing r
with respect to the modulus m
fromRepresentative :: C a => a > a > T aSource
errIncompat :: aSource
fromInteger :: C a => a > Integer > T aSource