module Group.Field
( module Group
, module Group.Field
) where
import Protolude
import Control.Monad.Random (Random(..))
import GaloisField (GaloisField(..))
import Test.Tasty.QuickCheck (Arbitrary(..), suchThatMap)
import Text.PrettyPrint.Leijen.Text (Pretty(..))
import Group (Group(..))
class GaloisField k => FGroup k where
{-# MINIMAL g_, q_, r_, x_ #-}
g_ :: Element k
q_ :: Element k -> Integer
r_ :: Element k -> Integer
x_ :: k
newtype Element k = F k
deriving (Eq, Functor, Generic, NFData, Read, Show)
instance FGroup k => Group (Element k) where
add = (<>)
{-# INLINABLE add #-}
dbl = join (<>)
{-# INLINABLE dbl #-}
def (F x) = x /= 0
{-# INLINABLE def #-}
gen = g_
{-# INLINABLE gen #-}
id = mempty
{-# INLINABLE id #-}
inv (F x) = F (recip x)
{-# INLINABLE inv #-}
mul' (F x) n = F (pow x n)
{-# INLINABLE mul' #-}
order = r_
{-# INLINABLE order #-}
instance FGroup k => Monoid (Element k) where
mempty = F 1
{-# INLINABLE mempty #-}
instance FGroup k => Semigroup (Element k) where
F x <> F y = F (x * y)
{-# INLINABLE (<>) #-}
instance FGroup k => Arbitrary (Element k) where
arbitrary = suchThatMap arbitrary defX
where
defX 0 = Nothing
defX x = Just (F x)
{-# INLINABLE arbitrary #-}
instance FGroup k => Pretty (Element k) where
pretty (F x) = pretty x
instance FGroup k => Random (Element k) where
random g = case random g of
(0, g') -> random g'
(x, g') -> (F x, g')
{-# INLINABLE random #-}
randomR = panic "not implemented."