finite-field 0.8.0 → 0.9.0
raw patch · 6 files changed
+306/−99 lines, 6 filesdep +singletonsdep +taggeddep +tastydep −HUnitdep −test-frameworkdep −test-framework-hunitdep ~QuickCheckdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: singletons, tagged, tasty, tasty-hunit, tasty-quickcheck, tasty-th
Dependencies removed: HUnit, test-framework, test-framework-hunit, test-framework-quickcheck2, test-framework-th
Dependency ranges changed: QuickCheck, base
API changes (from Hackage documentation)
- Data.FiniteField.PrimeField: instance Eq (PrimeField p)
- Data.FiniteField.PrimeField: instance NFData (PrimeField p)
- Data.FiniteField.PrimeField: instance Nat p => Bounded (PrimeField p)
- Data.FiniteField.PrimeField: instance Nat p => Enum (PrimeField p)
- Data.FiniteField.PrimeField: instance Nat p => FiniteField (PrimeField p)
- Data.FiniteField.PrimeField: instance Nat p => Fractional (PrimeField p)
- Data.FiniteField.PrimeField: instance Nat p => Hashable (PrimeField p)
- Data.FiniteField.PrimeField: instance Nat p => Num (PrimeField p)
- Data.FiniteField.PrimeField: instance Nat p => Read (PrimeField p)
- Data.FiniteField.PrimeField: instance Ord (PrimeField p)
- Data.FiniteField.PrimeField: instance Show (PrimeField p)
- Data.FiniteField.PrimeField: instance Typeable1 PrimeField
+ Data.FiniteField.PrimeField: instance Control.DeepSeq.NFData (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.Classes.Eq (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.Classes.Ord (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.Show.Show (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.TypeLits.KnownNat p => Data.FiniteField.Base.FiniteField (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.TypeLits.KnownNat p => Data.Hashable.Class.Hashable (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.TypeLits.KnownNat p => GHC.Enum.Bounded (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.TypeLits.KnownNat p => GHC.Enum.Enum (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.TypeLits.KnownNat p => GHC.Num.Num (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.TypeLits.KnownNat p => GHC.Read.Read (Data.FiniteField.PrimeField.PrimeField p)
+ Data.FiniteField.PrimeField: instance GHC.TypeLits.KnownNat p => GHC.Real.Fractional (Data.FiniteField.PrimeField.PrimeField p)
- Data.FiniteField.PrimeField: data PrimeField p
+ Data.FiniteField.PrimeField: data PrimeField (p :: Nat)
Files
- .gitignore +1/−0
- .travis.yml +74/−42
- README.md +1/−1
- finite-field.cabal +32/−11
- src/Data/FiniteField/PrimeField.hs +42/−19
- test/TestPrimeField.hs +156/−26
.gitignore view
@@ -5,3 +5,4 @@ *.chi *.chs.h .virthualenv+.stack-work
.travis.yml view
@@ -1,55 +1,87 @@-# NB: don't set `language: haskell` here+language: c+sudo: false -# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.-env:-# - GHCVER=6.12.3-# - GHCVER=7.0.1-# - GHCVER=7.0.2-# - GHCVER=7.0.3-# - GHCVER=7.0.4-# - GHCVER=7.2.1-# - GHCVER=7.2.2-# - GHCVER=7.4.1-# - GHCVER=7.4.2-# - GHCVER=7.6.1-# - GHCVER=7.6.2- - GHCVER=7.6.3-# - GHCVER=7.8.1 # see note about Alex/Happy- - GHCVER=7.8.2 # see note about Alex/Happy-# - GHCVER=head # see section about GHC HEAD snapshots+cache:+ directories:+ - $HOME/.cabsnap+ - $HOME/.cabal/packages -# Note: the distinction between `before_install` and `install` is not important.+before_cache:+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar++matrix:+ include:+ - env: CABALVER=1.18 GHCVER=7.6.3+ compiler: ": #GHC 7.6.3"+ addons: {apt: {packages: [cabal-install-1.18,ghc-7.6.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ - env: CABALVER=1.18 GHCVER=7.8.3 COVERAGE=1+ compiler: ": #GHC 7.8.3"+ addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ - env: CABALVER=1.22 GHCVER=7.10.3+ compiler: ": #GHC 7.10.3"+ addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ - env: CABALVER=1.24 GHCVER=8.0.1+ compiler: ": #GHC 8.0.1"+ addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}+ before_install:- - travis_retry sudo add-apt-repository -y ppa:hvr/ghc- - travis_retry sudo apt-get update- - travis_retry sudo apt-get install cabal-install-1.18 ghc-$GHCVER # see note about happy/alex- - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/1.18/bin:$PATH- - |- if [ $GHCVER = "head" ] || [ ${GHCVER%.*} = "7.8" ]; then- travis_retry sudo apt-get install happy-1.19.3 alex-3.1.3- export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.3/bin:$PATH+ - unset CC+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:/opt/alex/3.1.4/bin:/opt/happy/1.19.5/bin:~/.cabal/bin:$PATH++install:+ - cabal --version+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];+ then+ zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >+ $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;+ fi+ - travis_retry cabal update -v+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config+ - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt++# check whether current requested install-plan matches cached package-db snapshot+ - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;+ then+ echo "cabal build-cache HIT";+ rm -rfv .ghc;+ cp -a $HOME/.cabsnap/ghc $HOME/.ghc;+ cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/; else- travis_retry sudo apt-get install happy alex+ echo "cabal build-cache MISS";+ rm -rf $HOME/.cabsnap;+ mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;+ cabal install --only-dependencies --enable-tests --enable-benchmarks; fi -install:- - cabal update- - cabal install --only-dependencies --enable-tests -v2 # -v2 provides useful information for debugging+# snapshot package-db on cache miss+ - if [ ! -d $HOME/.cabsnap ];+ then+ echo "snapshotting package-db to build-cache";+ mkdir $HOME/.cabsnap;+ cp -a $HOME/.ghc $HOME/.cabsnap/ghc;+ cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;+ fi -# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.+# Here starts the actual work to be performed for the package under test;+# any command which exits with a non-zero exit code causes the build to fail. script:- - cabal configure --enable-tests -v2 # -v2 provides useful information for debugging+ - if [ -f configure.ac ]; then autoreconf -i; fi+ - cabal configure --enable-tests --enable-benchmarks -v2 $([ "$COVERAGE" = "1" ] && echo "--enable-library-coverage") # -v2 provides useful information for debugging - cabal build # this builds all libraries and executables (including tests/benchmarks) - cabal test - cabal check - cabal sdist # tests that a source-distribution can be generated -# The following scriptlet checks that the resulting source distribution can be built & installed- - export SRC_TGZ=$(cabal-1.18 info . | awk '{print $2 ".tar.gz";exit}') ;- cd dist/;- if [ -f "$SRC_TGZ" ]; then- cabal install "$SRC_TGZ";- else- echo "expected '$SRC_TGZ' not found";- exit 1;- fi+# Check that the resulting source distribution can be built & installed.+# If there are no other `.tar.gz` files in `dist`, this can be even simpler:+# `cabal install --force-reinstalls dist/*-*.tar.gz`+ - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&+ (cd dist && cabal install --force-reinstalls "$SRC_TGZ")++# This block must be executed before before_cache+#after_script:+ - "[ -n \"$COVERAGE\" ] && cabal install hpc-coveralls --avoid-reinstalls --constraint=\"regex-posix >=0.95.2\" || true" # regex-posix-0.95.1 has compilation problem+ - "[ -n \"$COVERAGE\" ] && hpc-coveralls TestPrimeField --exclude-dir=test || true"
README.md view
@@ -1,4 +1,4 @@ finite-field ============ -[](http://travis-ci.org/msakai/finite-field)+[](http://travis-ci.org/msakai/finite-field) [](https://hackage.haskell.org/package/finite-field) [](https://coveralls.io/r/msakai/finite-field)
finite-field.cabal view
@@ -1,5 +1,5 @@ Name: finite-field-Version: 0.8.0+Version: 0.9.0 License: BSD3 License-File: COPYING Author: Masahiro Sakai (masahiro.sakai@gmail.com)@@ -19,6 +19,11 @@ .gitignore Build-Type: Simple +Flag UseGHCTypeLits+ Description: set GHC.TypeLits module+ Default: True+ Manual: True+ source-repository head type: git location: git://github.com/msakai/finite-field.git@@ -26,9 +31,15 @@ Library Hs-source-dirs: src Build-Depends:- base >=4 && <5, template-haskell, deepseq, hashable, type-level-numbers >=0.1.1.0 && <0.2.0.0+ base >=4 && <5, template-haskell, deepseq, hashable+ if flag(UseGHCTypeLits)+ Build-Depends: base >=4.7, singletons >=1.0+ CPP-OPtions: "-DUseGHCTypeLits"+ else+ Build-Depends: type-level-numbers >=0.1.1.0 && <0.2.0.0 Default-Language: Haskell2010 Other-Extensions:+ ConstraintKinds DeriveDataTypeable MultiParamTypeClasses ScopedTypeVariables@@ -48,14 +59,24 @@ Build-depends: base >=4 && <5, containers,- test-framework,- test-framework-th,- test-framework-hunit,- test-framework-quickcheck2,- HUnit,- QuickCheck >=2 && <3,+ deepseq,+ hashable,+ tasty >=0.10.1,+ tasty-hunit ==0.9.*,+ tasty-quickcheck ==0.8.*,+ tasty-th,+ QuickCheck >=2.5 && <3, finite-field,- primes,- type-level-numbers >=0.1.1.0 && <0.2.0.0+ primes+ if flag(UseGHCTypeLits)+ Build-Depends: base >=4.7, singletons >=1.0+ CPP-OPtions: "-DUseGHCTypeLits"+ else+ Build-depends: type-level-numbers >=0.1.1.0 && <0.2.0.0+ if impl(ghc<7.7)+ Build-Depends: tagged Default-Language: Haskell2010- Other-Extensions: TemplateHaskell+ Other-Extensions:+ TemplateHaskell+ ScopedTypeVariables+ CPP
src/Data/FiniteField/PrimeField.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, BangPatterns #-}+{-# LANGUAGE CPP, KindSignatures, DataKinds, ConstraintKinds #-} {-# OPTIONS_GHC -Wall #-} ----------------------------------------------------------------------------- -- | -- Module : Data.FiniteField.PrimeField--- Copyright : (c) Masahiro Sakai 2013+-- Copyright : (c) Masahiro Sakai 2013-2014 -- License : BSD-style -- -- Maintainer : masahiro.sakai@gmail.com@@ -31,14 +32,26 @@ import Data.Ratio (denominator, numerator) import Data.Typeable import qualified Language.Haskell.TH as TH+#if !defined(UseGHCTypeLits) import qualified TypeLevel.Number.Nat as TL+#else+import GHC.TypeLits+#endif import Data.FiniteField.Base -- | Finite field of prime order p, Fp = Z/pZ. -- -- NB: Primality of @p@ is assumed, but not checked.+#if !defined(UseGHCTypeLits) newtype PrimeField p = PrimeField Integer deriving (Eq, Typeable)+#else+newtype PrimeField (p::Nat) = PrimeField Integer deriving (Eq, Typeable)+#endif +#if !defined(UseGHCTypeLits)+type KnownNat p = TL.Nat p+#endif+ -- | conversion to 'Integer' toInteger :: PrimeField p -> Integer toInteger (PrimeField a) = a@@ -49,36 +62,40 @@ instance Show (PrimeField p) where showsPrec n (PrimeField x) = showsPrec n x -instance TL.Nat p => Read (PrimeField p) where+instance KnownNat p => Read (PrimeField p) where readsPrec n s = [(fromInteger a, s') | (a,s') <- readsPrec n s] instance NFData (PrimeField p) where rnf (PrimeField a) = rnf a -instance TL.Nat p => Num (PrimeField p) where+instance KnownNat p => Num (PrimeField p) where PrimeField a + PrimeField b = fromInteger $ a+b PrimeField a * PrimeField b = fromInteger $ a*b PrimeField a - PrimeField b = fromInteger $ a-b negate (PrimeField a) = fromInteger $ negate a abs a = a signum _ = 1- fromInteger a = PrimeField $ a `mod` TL.toInt (undefined :: p)+ fromInteger a = ret+ where+ ret = PrimeField $ a `mod` char ret -instance TL.Nat p => Fractional (PrimeField p) where+instance KnownNat p => Fractional (PrimeField p) where fromRational r = fromInteger (numerator r) / fromInteger (denominator r)--- recip a = a ^ (TL.toInt (undefined :: p) - 2 :: Integer)- recip (PrimeField a) =+-- recip a = a ^ (char a - 2 :: Integer)+ recip x@(PrimeField a) = case exgcd a p of (_, r, _) -> fromInteger r where p :: Integer- p = TL.toInt (undefined :: p)+ p = char x -instance TL.Nat p => Bounded (PrimeField p) where+instance KnownNat p => Bounded (PrimeField p) where minBound = PrimeField 0- maxBound = PrimeField (TL.toInt (undefined :: p) - 1)+ maxBound = ret+ where+ ret = PrimeField (char ret - 1) -instance TL.Nat p => Enum (PrimeField p) where+instance KnownNat p => Enum (PrimeField p) where toEnum x | toInt (minBound :: PrimeField p) <= x && x <= toInt (maxBound :: PrimeField p) = fromIntegral x | otherwise = error "PrimeField.toEnum: bad argument"@@ -86,21 +103,23 @@ instance Ord (PrimeField p) where PrimeField a `compare` PrimeField b = a `compare` b- PrimeField a `max` PrimeField b = PrimeField (a `max` b)- PrimeField a `min` PrimeField b = PrimeField (a `min` b) -instance TL.Nat p => FiniteField (PrimeField p) where- order _ = TL.toInt (undefined :: p)+instance KnownNat p => FiniteField (PrimeField p) where+ order x = char x+#if !defined(UseGHCTypeLits) char _ = TL.toInt (undefined :: p)+#else+ char _ = natVal (Proxy :: Proxy p)+#endif pthRoot a = a allValues = [minBound .. maxBound] -instance TL.Nat p => Hashable (PrimeField p) where- hashWithSalt s (PrimeField a) =- s `hashWithSalt` (TL.toInt (undefined :: p) :: Int) `hashWithSalt` a+instance KnownNat p => Hashable (PrimeField p) where+ hashWithSalt s x@(PrimeField a) =+ s `hashWithSalt` char x `hashWithSalt` a -- | Extended GCD algorithm-exgcd :: (Eq a, Integral a) => a -> a -> (a, a, a)+exgcd :: Integral a => a -> a -> (a, a, a) exgcd f1 f2 = f $ go f1 f2 1 0 0 1 where go !r0 !r1 !s0 !s1 !t0 !t1@@ -120,7 +139,11 @@ primeField :: Integer -> TH.TypeQ primeField n | n <= 0 = error "primeField: negative value"+#if !defined(UseGHCTypeLits) | otherwise = [t| PrimeField $(TL.natT n) |]+#else+ | otherwise = [t| PrimeField $(TH.litT (TH.numTyLit n)) |]+#endif -- $TH -- Here is usage example for primeField:
test/TestPrimeField.hs view
@@ -1,83 +1,102 @@-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell, ScopedTypeVariables, GADTs, DataKinds, CPP #-} {-# OPTIONS_GHC -fcontext-stack=32 #-} -import Test.HUnit hiding (Test)-import Test.QuickCheck-import Test.Framework.TH-import Test.Framework.Providers.QuickCheck2-import Test.Framework.Providers.HUnit+import Prelude hiding (toInteger) +import Test.Tasty+import Test.Tasty.QuickCheck+import Test.Tasty.HUnit+import Test.Tasty.TH+import qualified Test.QuickCheck.Monadic as QM++import Control.DeepSeq+import Control.Exception import Control.Monad+import Data.Either+import Data.Hashable import Data.List (genericLength) import Data.Numbers.Primes (primes)+import Data.Proxy+import Data.Ratio import Data.FiniteField+#ifdef UseGHCTypeLits+import Data.Maybe+import GHC.TypeLits+#else import TypeLevel.Number.Nat+#endif -- ---------------------------------------------------------------------- -- addition prop_add_comm =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> forAll arbitrary $ \b -> a + b == b + a prop_add_assoc =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> forAll arbitrary $ \b -> forAll arbitrary $ \c -> (a + b) + c == a + (b + c) prop_add_unitl =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> 0 + a == a prop_add_unitr =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> a + 0 == a prop_negate =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> a + negate a == 0 +prop_sub_negate =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ forAll arbitrary $ \(b :: PrimeField p) ->+ a - b == a + negate b+ -- ---------------------------------------------------------------------- -- multiplication prop_mult_comm =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> forAll arbitrary $ \b -> a * b == b * a prop_mult_assoc =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> forAll arbitrary $ \b -> forAll arbitrary $ \c -> (a * b) * c == a * (b * c) prop_mult_unitl =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> 1 * a == a prop_mult_unitr =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> a * 1 == a prop_mult_zero_l =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> 0*a == 0 prop_mult_zero_r =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> a*0 == 0 @@ -85,41 +104,111 @@ -- distributivity prop_distl =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> forAll arbitrary $ \b -> forAll arbitrary $ \c -> a * (b + c) == a*b + a*c prop_distr =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> forAll arbitrary $ \b -> forAll arbitrary $ \c -> (b + c) * a == b*a + c*a -- ------------------------------------------------------------------------- recip+-- misc Num methods +prop_abs =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ abs a == a++prop_signum =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ signum a == 1++-- ----------------------------------------------------------------------+-- Fractional++prop_fromRational =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(r :: Rational) ->+ (fromRational r :: PrimeField p) == fromInteger (numerator r) / fromInteger (denominator r)+ prop_recip =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> a /= 0 ==> a * (recip a) == 1 -- ------------------------------------------------------------------------- FiniteField type class+-- FiniteField prop_pthRoot =- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> forAll arbitrary $ \(a :: PrimeField p) -> pthRoot a ^ char a == a prop_allValues = do- forAll smallPrimes $ \(SomeNat (_ :: p)) ->+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) -> genericLength (allValues :: [PrimeField p]) == order (undefined :: PrimeField p) -- ----------------------------------------------------------------------+-- Show / Read +prop_read_show =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ read (show a) == a ++-- ----------------------------------------------------------------------+-- Ord++prop_zero_minimum =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ 0 <= a++-- ----------------------------------------------------------------------+-- NFData++prop_rnf =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ rnf a == ()++-- ----------------------------------------------------------------------+-- Enum++prop_toEnum_fromEnum =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ toEnum (fromEnum a) == a++prop_toEnum_negative = QM.monadicIO $ do+ SomeNat' (_ :: Proxy p) <- QM.pick smallPrimes+ let a :: PrimeField p+ a = toEnum (-1)+ (ret :: Either SomeException (PrimeField p)) <- QM.run $ try $ evaluate $ a+ QM.assert $ isLeft ret++-- ----------------------------------------------------------------------++prop_hash =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ hash a `seq` () == ()++-- ----------------------------------------------------------------------+-- misc++prop_fromInteger_toInteger =+ forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->+ forAll arbitrary $ \(a :: PrimeField p) ->+ fromInteger (toInteger a) == a+ case_primeFieldT = a @?= 1 where a :: $(primeField 15485867)@@ -127,12 +216,41 @@ ------------------------------------------------------------------------ -smallPrimes :: Gen SomeNat+#ifdef UseGHCTypeLits++data SomeNat' where+ SomeNat' :: KnownNat p => Proxy p -> SomeNat'++instance Show SomeNat' where+ showsPrec p (SomeNat' x) = showsPrec p (natVal x)++#else++data SomeNat' where+ SomeNat' :: Nat p => Proxy p -> SomeNat'++instance Show SomeNat' where+ showsPrec p (SomeNat' (x :: Proxy p)) = showsPrec p (toInt (undefined :: p))++#endif++smallPrimes :: Gen SomeNat' smallPrimes = do i <- choose (0, 2^(16::Int))- return $ withNat SomeNat (primes !! i)+#ifdef UseGHCTypeLits+ case fromJust $ someNatVal $ primes !! i of+ SomeNat proxy -> return $ SomeNat' proxy+#else+ let f :: forall p. Nat p => p -> SomeNat'+ f _ = SomeNat' (Proxy :: Proxy p)+ return $ withNat f (primes !! i)+#endif +#ifdef UseGHCTypeLits+instance KnownNat p => Arbitrary (PrimeField p) where+#else instance Nat p => Arbitrary (PrimeField p) where+#endif arbitrary = liftM fromInteger arbitrary ------------------------------------------------------------------------@@ -140,3 +258,15 @@ main :: IO () main = $(defaultMainGenerator)++#if !MIN_VERSION_base(4,7,0)++isLeft :: Either a b -> Bool+isLeft (Left _) = True+isLeft (Right _) = False++isRight :: Either a b -> Bool+isRight (Left _) = False+isRight (Right _) = True++#endif