{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Crypto.Lol.Types.Unsafe.RRq
( RRq(..)
) where
import Algebra.Additive as Additive (C)
import Algebra.ZeroTestable as ZeroTestable (C)
import Control.DeepSeq
import System.Random
import Crypto.Lol.Prelude
import Crypto.Lol.Reflects
import Crypto.Lol.Types.Unsafe.ZqBasic hiding (ZqB)
newtype RRq q r = RRq r
deriving (Eq, ZeroTestable.C, Show, NFData)
instance RealField r => Additive.C (RRq q r) where
{-# INLINABLE zero #-}
zero = RRq zero
{-# INLINABLE (+) #-}
(RRq x) + (RRq y) = RRq $ fraction $ x + y
{-# INLINABLE negate #-}
negate (RRq x) = RRq $ fraction $ negate x
reduce' :: forall q r . (Reflects q r, RealField r) => r -> RRq q r
reduce' r = RRq $ fraction $ r / value @q
instance (Reflects q r, RealField r) => Reduce r (RRq q r) where
reduce = reduce'
type instance LiftOf (RRq q r) = r
instance (Reflects q r, Field r, Reduce r (RRq q r))
=> Lift' (RRq q r) where
lift (RRq r) = (r-0.5) * value @q
instance (Additive (RRq q r), Additive (RRq p r))
=> Rescale (RRq q r) (RRq p r) where
rescale (RRq r) = RRq r
instance Random (RRq q Double) where
random g = let (r,g') = random g in (RRq r, g')
randomR = error "randomR is nonsensical for RRq"
instance (ToInteger z, RealField r, Reflects q z, Reflects q r)
=> Subgroup (ZqBasic q z) (RRq q r) where
fromSubgroup = reduce' . fromIntegral . lift