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 moduli of arbitrary size.
Use Data.Mod.Word to achieve better performance,
when your moduli fit into Word
.
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 -> Natural 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 much 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