smart-math-0.1: Mathematical smart constructors
Safe HaskellNone
LanguageHaskell2010

Numeric.Data.ModP

Description

Provides the ModP type for modular arithmetic.

Since: 0.1

Synopsis

Type

data ModP (p :: Nat) a where Source #

Newtype wrapper that represents \( \mathbb{Z}/p\mathbb{Z} \) for prime p. ModP is a Field i.e. supports addition, subtraction, multiplication, and division.

When constructing a ModP p a we must verify that p is prime and the type a is large enough to accommodate p, hence the possible failure.

Examples

Expand
>>> import Data.Text.Display (display)
>>> display $ unsafeModP @7 10
"3 (mod 7)"

Since: 0.1

Bundled Patterns

pattern MkModP :: a -> ModP p a

Unidirectional pattern synonym for ModP. This allows us to pattern match on a modp term without exposing the unsafe internal details.

Since: 0.1

Instances

Instances details
HasField "unModP" (ModP p a) a Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

getField :: ModP p a -> a #

(k ~ A_Getter, x ~ a, y ~ a) => LabelOptic "unModP" k (ModP p a) (ModP p a) x y Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

labelOptic :: Optic k NoIx (ModP p a) (ModP p a) x y Source #

Lift a => Lift (ModP p a :: Type) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

lift :: Quote m => ModP p a -> m Exp #

liftTyped :: forall (m :: Type -> Type). Quote m => ModP p a -> Code m (ModP p a) #

(AnyLowerBounded a, AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => AGroup (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

(.-.) :: ModP p a -> ModP p a -> ModP p a Source #

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => AMonoid (ModP p a) Source #

WARNING: Partial

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

zero :: ModP p a Source #

(AnyUpperBounded a, Integral a, KnownNat p) => ASemigroup (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

(.+.) :: ModP p a -> ModP p a -> ModP p a Source #

(AnyLowerBounded a, AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => Field (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => MGroup (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

(.%.) :: ModP p a -> ModP p a -> ModP p a Source #

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => MMonoid (ModP p a) Source #

WARNING: Partial

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

one :: ModP p a Source #

(AnyUpperBounded a, Integral a, KnownNat p) => MSemigroup (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

(.*.) :: ModP p a -> ModP p a -> ModP p a Source #

(AnyLowerBounded a, AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => Ring (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => Semifield (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => Semiring (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => FromInteger (ModP p a) Source #

WARNING: Partial

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

afromInteger :: Integer -> ModP p a Source #

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => Bounded (ModP p a) Source #

WARNING: Partial

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

minBound :: ModP p a #

maxBound :: ModP p a #

Generic (ModP p a) Source # 
Instance details

Defined in Numeric.Data.ModP.Internal

Associated Types

type Rep (ModP p a)

Since: smart-math-0.1

Instance details

Defined in Numeric.Data.ModP.Internal

type Rep (ModP p a) = D1 ('MetaData "ModP" "Numeric.Data.ModP.Internal" "smart-math-0.1-inplace" 'True) (C1 ('MetaCons "UnsafeModP" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

Methods

from :: ModP p a -> Rep (ModP p a) x #

to :: Rep (ModP p a) x -> ModP p a #

(KnownNat p, Show a) => Show (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

showsPrec :: Int -> ModP p a -> ShowS #

show :: ModP p a -> String #

showList :: [ModP p a] -> ShowS #

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => LowerBounded (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

lowerBound :: ModP p a Source #

(AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => UpperBounded (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

upperBound :: ModP p a Source #

NFData a => NFData (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

rnf :: ModP p a -> () #

Eq a => Eq (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

(==) :: ModP p a -> ModP p a -> Bool #

(/=) :: ModP p a -> ModP p a -> Bool #

Ord a => Ord (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

Methods

compare :: ModP p a -> ModP p a -> Ordering #

(<) :: ModP p a -> ModP p a -> Bool #

(<=) :: ModP p a -> ModP p a -> Bool #

(>) :: ModP p a -> ModP p a -> Bool #

(>=) :: ModP p a -> ModP p a -> Bool #

max :: ModP p a -> ModP p a -> ModP p a #

min :: ModP p a -> ModP p a -> ModP p a #

(KnownNat p, Show a) => Display (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

type Rep (ModP p a) Source #

Since: 0.1

Instance details

Defined in Numeric.Data.ModP.Internal

type Rep (ModP p a) = D1 ('MetaData "ModP" "Numeric.Data.ModP.Internal" "smart-math-0.1-inplace" 'True) (C1 ('MetaCons "UnsafeModP" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

Creation

mkModP :: forall (p :: Nat) a. (AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => a -> Either String (ModP p a) Source #

Constructor for ModP. Fails if p is not prime. This uses the Miller-Rabin primality test, which has complexity \(O(k \log^3 p)\), and we take \(k = 100\). See wikipedia for more details.

Examples

Expand
>>> mkModP @5 7
Right (MkModP 2 (mod 5))
>>> mkModP @10 7
Left "Received non-prime: 10"
>>> mkModP @128 (9 :: Int8)
Left "Type 'Int8' has a maximum size of 127. This is not large enough to safely implement mod 128."

Since: 0.1

mkModPTH :: forall (p :: Nat) a. (AnyUpperBounded a, Integral a, KnownNat p, Lift a, Typeable a) => a -> Code Q (ModP p a) Source #

Template haskell for creating a ModP at compile-time.

Examples

Expand
>>> $$(mkModPTH @11 7)
MkModP 7 (mod 11)

Since: 0.1

unsafeModP :: forall (p :: Nat) a. (AnyUpperBounded a, HasCallStack, Integral a, KnownNat p, Typeable a) => a -> ModP p a Source #

Variant of mkModP that throws an error when given a non-prime.

WARNING: Partial

Examples

Expand
>>> unsafeModP @7 12
MkModP 5 (mod 7)

Since: 0.1

reallyUnsafeModP :: forall (p :: Nat) a. (Integral a, KnownNat p) => a -> ModP p a Source #

This function reduces the argument modulo p but does not check that p is prime. Note that the correct behavior of some functionality (e.g. division) is reliant on primality, so this is dangerous. This is intended only for when we absolutely know p is prime and the check is undesirable for performance reasons. Exercise extreme caution.

Since: 0.1

Elimination

unModP :: forall (p :: Nat) a. ModP p a -> a Source #

Since: 0.1

Functions

invert :: forall (p :: Nat) a. (Integral a, KnownNat p) => ModP p a -> ModP p a Source #

Given non-zero \(d\), returns the inverse i.e. finds \(e\) s.t.

\[ de \equiv 1 \pmod p. \]

Examples

Expand

findInverse >>> invert $ unsafeModP @7 5 MkModP 3 (mod 7)

>>> invert $ unsafeModP @19 12
MkModP 8 (mod 19)

Since: 0.1

Optics

We provide a ReversedPrism' _MkModP that allows for total elimination and partial construction, along with a LabelOptic Getter for #unModP.

Examples

Expand
>>> :set -XOverloadedLabels
>>> import Optics.Core (view)
>>> let n = $$(mkModPTH @7 9)
>>> view #unModP n
2

_MkModP :: forall (p :: Nat) a. (AnyUpperBounded a, Integral a, KnownNat p, Typeable a) => ReversedPrism' (ModP p a) a Source #

ReversedPrism' that enables total elimination and partial construction.

Examples

Expand
>>> import Optics.Core (view)
>>> n = $$(mkModPTH @7 9)
>>> view _MkModP n
2
>>> rmatching (_MkModP @7) 9
Right (MkModP 2 (mod 7))
>>> rmatching (_MkModP @6) 9
Left 9

Since: 0.1

rmatching :: (Is (ReversedOptic k) An_AffineTraversal, ReversibleOptic k) => Optic k NoIx b a t s -> s -> Either t a Source #

Reversed matching. Useful with smart-constructor optics.

Since: 0.1