{-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs              #-}
{-# LANGUAGE MultiParamTypeClasses, NoMonomorphismRestriction        #-}
{-# LANGUAGE ScopedTypeVariables, TypeFamilies, UndecidableInstances #-}
module Algebra.Field.Finite.Test
       (WrapFiniteField(..), arbitraryFiniteField, seriesFiniteField
       )where
import           Algebra.Field.Finite   (FiniteField (..))
import qualified Algebra.Field.Finite   as FF
import           Data.Coerce            (coerce)
import           Prelude
import           Test.QuickCheck        (Arbitrary (..), Gen)
import qualified Test.QuickCheck        as QC
import           Test.SmallCheck.Series (Serial (..), Series, generate)

newtype WrapFiniteField k = WrapFiniteField { WrapFiniteField k -> k
runWrapFiniteField :: k }
                            deriving (ReadPrec [WrapFiniteField k]
ReadPrec (WrapFiniteField k)
Int -> ReadS (WrapFiniteField k)
ReadS [WrapFiniteField k]
(Int -> ReadS (WrapFiniteField k))
-> ReadS [WrapFiniteField k]
-> ReadPrec (WrapFiniteField k)
-> ReadPrec [WrapFiniteField k]
-> Read (WrapFiniteField k)
forall k. Read k => ReadPrec [WrapFiniteField k]
forall k. Read k => ReadPrec (WrapFiniteField k)
forall k. Read k => Int -> ReadS (WrapFiniteField k)
forall k. Read k => ReadS [WrapFiniteField k]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [WrapFiniteField k]
$creadListPrec :: forall k. Read k => ReadPrec [WrapFiniteField k]
readPrec :: ReadPrec (WrapFiniteField k)
$creadPrec :: forall k. Read k => ReadPrec (WrapFiniteField k)
readList :: ReadS [WrapFiniteField k]
$creadList :: forall k. Read k => ReadS [WrapFiniteField k]
readsPrec :: Int -> ReadS (WrapFiniteField k)
$creadsPrec :: forall k. Read k => Int -> ReadS (WrapFiniteField k)
Read, Int -> WrapFiniteField k -> ShowS
[WrapFiniteField k] -> ShowS
WrapFiniteField k -> String
(Int -> WrapFiniteField k -> ShowS)
-> (WrapFiniteField k -> String)
-> ([WrapFiniteField k] -> ShowS)
-> Show (WrapFiniteField k)
forall k. Show k => Int -> WrapFiniteField k -> ShowS
forall k. Show k => [WrapFiniteField k] -> ShowS
forall k. Show k => WrapFiniteField k -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WrapFiniteField k] -> ShowS
$cshowList :: forall k. Show k => [WrapFiniteField k] -> ShowS
show :: WrapFiniteField k -> String
$cshow :: forall k. Show k => WrapFiniteField k -> String
showsPrec :: Int -> WrapFiniteField k -> ShowS
$cshowsPrec :: forall k. Show k => Int -> WrapFiniteField k -> ShowS
Show, WrapFiniteField k -> WrapFiniteField k -> Bool
(WrapFiniteField k -> WrapFiniteField k -> Bool)
-> (WrapFiniteField k -> WrapFiniteField k -> Bool)
-> Eq (WrapFiniteField k)
forall k. Eq k => WrapFiniteField k -> WrapFiniteField k -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WrapFiniteField k -> WrapFiniteField k -> Bool
$c/= :: forall k. Eq k => WrapFiniteField k -> WrapFiniteField k -> Bool
== :: WrapFiniteField k -> WrapFiniteField k -> Bool
$c== :: forall k. Eq k => WrapFiniteField k -> WrapFiniteField k -> Bool
Eq, Eq (WrapFiniteField k)
Eq (WrapFiniteField k)
-> (WrapFiniteField k -> WrapFiniteField k -> Ordering)
-> (WrapFiniteField k -> WrapFiniteField k -> Bool)
-> (WrapFiniteField k -> WrapFiniteField k -> Bool)
-> (WrapFiniteField k -> WrapFiniteField k -> Bool)
-> (WrapFiniteField k -> WrapFiniteField k -> Bool)
-> (WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k)
-> (WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k)
-> Ord (WrapFiniteField k)
WrapFiniteField k -> WrapFiniteField k -> Bool
WrapFiniteField k -> WrapFiniteField k -> Ordering
WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall k. Ord k => Eq (WrapFiniteField k)
forall k. Ord k => WrapFiniteField k -> WrapFiniteField k -> Bool
forall k.
Ord k =>
WrapFiniteField k -> WrapFiniteField k -> Ordering
forall k.
Ord k =>
WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k
min :: WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k
$cmin :: forall k.
Ord k =>
WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k
max :: WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k
$cmax :: forall k.
Ord k =>
WrapFiniteField k -> WrapFiniteField k -> WrapFiniteField k
>= :: WrapFiniteField k -> WrapFiniteField k -> Bool
$c>= :: forall k. Ord k => WrapFiniteField k -> WrapFiniteField k -> Bool
> :: WrapFiniteField k -> WrapFiniteField k -> Bool
$c> :: forall k. Ord k => WrapFiniteField k -> WrapFiniteField k -> Bool
<= :: WrapFiniteField k -> WrapFiniteField k -> Bool
$c<= :: forall k. Ord k => WrapFiniteField k -> WrapFiniteField k -> Bool
< :: WrapFiniteField k -> WrapFiniteField k -> Bool
$c< :: forall k. Ord k => WrapFiniteField k -> WrapFiniteField k -> Bool
compare :: WrapFiniteField k -> WrapFiniteField k -> Ordering
$ccompare :: forall k.
Ord k =>
WrapFiniteField k -> WrapFiniteField k -> Ordering
$cp1Ord :: forall k. Ord k => Eq (WrapFiniteField k)
Ord)

instance FiniteField k => Arbitrary (WrapFiniteField k) where
  arbitrary :: Gen (WrapFiniteField k)
arbitrary = Gen k -> Gen (WrapFiniteField k)
coerce (Gen k -> Gen (WrapFiniteField k))
-> Gen k -> Gen (WrapFiniteField k)
forall a b. (a -> b) -> a -> b
$ [k] -> Gen k
forall a. [a] -> Gen a
QC.elements ([k] -> [k]
forall k (proxy :: * -> *). FiniteField k => proxy k -> [k]
FF.elements ([] :: [k]))

arbitraryFiniteField :: FiniteField k => proxy k -> Gen k
arbitraryFiniteField :: proxy k -> Gen k
arbitraryFiniteField proxy k
_ = WrapFiniteField k -> k
forall k. WrapFiniteField k -> k
runWrapFiniteField (WrapFiniteField k -> k) -> Gen (WrapFiniteField k) -> Gen k
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (WrapFiniteField k)
forall a. Arbitrary a => Gen a
arbitrary

instance (Monad m, FiniteField k) => Serial m (WrapFiniteField k) where
  series :: Series m (WrapFiniteField k)
series = (Int -> [WrapFiniteField k]) -> Series m (WrapFiniteField k)
forall a (m :: * -> *). (Int -> [a]) -> Series m a
generate ((Int -> [WrapFiniteField k]) -> Series m (WrapFiniteField k))
-> (Int -> [WrapFiniteField k]) -> Series m (WrapFiniteField k)
forall a b. (a -> b) -> a -> b
$ \Int
n ->
    [k] -> [WrapFiniteField k]
coerce ([k] -> [WrapFiniteField k]) -> [k] -> [WrapFiniteField k]
forall a b. (a -> b) -> a -> b
$ Int -> [k] -> [k]
forall a. Int -> [a] -> [a]
take Int
n ([k] -> [k]) -> [k] -> [k]
forall a b. (a -> b) -> a -> b
$ [k] -> [k]
forall k (proxy :: * -> *). FiniteField k => proxy k -> [k]
FF.elements ([] :: [k])

seriesFiniteField :: (FiniteField k, Monad m) => proxy k -> Series m k
seriesFiniteField :: proxy k -> Series m k
seriesFiniteField proxy k
_ = WrapFiniteField k -> k
forall k. WrapFiniteField k -> k
runWrapFiniteField (WrapFiniteField k -> k)
-> Series m (WrapFiniteField k) -> Series m k
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Series m (WrapFiniteField k)
forall (m :: * -> *) a. Serial m a => Series m a
series