Copyright | (c) 2017-2020 Andrew Lelechenko |
---|---|
License | MIT |
Maintainer | Andrew Lelechenko <andrew.lelechenko@gmail.com> |
Safe Haskell | None |
Language | Haskell2010 |
Modular arithmetic, promoting moduli to the type level, with an emphasis on performance. Originally part of arithmoi package.
This module supports only moduli, which fit into Word
.
Use (slower) Data.Mod to handle arbitrary-sized moduli.
Documentation
This data type represents integers modulo m, equipped with useful instances.
For example, 3 :: Mod
10 stands for the class of integers
congruent to \( 3 \bmod 10 \colon \ldots {−17}, −7, 3, 13, 23 \ldots \)
>>>
:set -XDataKinds
>>>
3 + 8 :: Mod 10 -- 3 + 8 = 11 ≡ 1 (mod 10)
(1 `modulo` 10)
Warning: division by residue, which is not
coprime
with the modulo, throws DivideByZero
.
Consider using invertMod
for non-prime moduli.
Instances
unMod :: Mod m -> Word Source #
The canonical representative of the residue class, always between 0 and \( m - 1 \) inclusively.
>>>
:set -XDataKinds
>>>
-1 :: Mod 10
(9 `modulo` 10)
(^%) :: (KnownNat m, Integral a) => Mod m -> a -> Mod m infixr 8 Source #
Drop-in replacement for ^
with a bit better performance.
Negative powers are allowed, but may throw DivideByZero
, if an argument
is not coprime with the modulo.
Building with -O
triggers a rewrite rule ^
= ^%
.
>>>
:set -XDataKinds
>>>
3 ^% 4 :: Mod 10 -- 3 ^ 4 = 81 ≡ 1 (mod 10)
(1 `modulo` 10)>>>
3 ^% (-1) :: Mod 10 -- 3 * 7 = 21 ≡ 1 (mod 10)
(7 `modulo` 10)>>>
4 ^% (-1) :: Mod 10 -- 4 and 10 are not coprime
(*** Exception: divide by zero