{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Crypto.Lol.Cyclotomic.CycRep
(
CycRep, P, D, C, E, CycRepEC, CycRepPC, CRTElt
, toPow, toDec, toCRT
, scalarPow, scalarCRT
, mulGPow, mulGDec, mulGCRTC, divGPow, divGDec, divGCRTC, gSqNormDec
, tweakedGaussian, roundedGaussian, cosetGaussian
, embedPow, embedCRTC, embedCRTE
, twacePow, twaceDec, twaceCRTC, twaceCRTE
, coeffsPow, coeffsDec, powBasis, crtSet
) where
import Crypto.Lol.CRTrans
import Crypto.Lol.Cyclotomic.CRTSentinel
import Crypto.Lol.Cyclotomic.Tensor hiding (divGDec, divGPow,
embedCRT, embedPow, gSqNormDec,
mulGDec, mulGPow, scalarCRT,
scalarPow, twaceCRT)
import Crypto.Lol.Prelude as LP
import Crypto.Lol.Reflects
import Crypto.Lol.Types.FiniteField
import Crypto.Lol.Types.IFunctor
import Crypto.Lol.Types.Proto
import Crypto.Lol.Types.Unsafe.ZqBasic
import qualified Crypto.Lol.Cyclotomic.Tensor as T
import qualified Algebra.Additive as Additive (C)
import qualified Algebra.Module as Module (C)
import qualified Algebra.Ring as Ring (C)
import qualified Algebra.ZeroTestable as ZeroTestable (C)
import Control.Applicative as A
import Control.DeepSeq
import Control.Monad.Identity (Identity (..))
import Control.Monad.Random hiding (ap, lift)
import Data.Foldable as F
import Data.Traversable
data P
data D
data C
data E
data family CycRep (t :: Factored -> * -> *) rep (m :: Factored) r
newtype instance CycRep t P m r = Pow (t m r) deriving (Eq, ZeroTestable.C)
newtype instance CycRep t D m r = Dec (t m r) deriving (Eq, ZeroTestable.C)
data instance CycRep t C m r = CRTC !(CSentinel t m r) !(t m r) deriving (Eq)
data instance CycRep t E m r = CRTE !(ESentinel t m r) !(t m (CRTExt r))
type CycRepEC t m r = Either (CycRep t E m r) (CycRep t C m r)
type CycRepPC t m r = Either (CycRep t P m r) (CycRep t C m r)
type CRTElt t r = (TensorG t r, CRTEmbed r,
TensorCRT t Maybe r, TensorCRT t Identity (CRTExt r))
scalarPow :: (TensorPowDec t r, Fact m) => r -> CycRep t P m r
scalarPow = Pow . T.scalarPow
{-# INLINABLE scalarPow #-}
scalarCRT :: (Fact m, CRTElt t r) => r -> CycRepEC t m r
scalarCRT r = case crtSentinel of
Right s -> Right $ CRTC s $ scalarCRTCS s r
Left s -> Left $ CRTE s $ runIdentity T.scalarCRT $ toExt r
{-# INLINABLE scalarCRT #-}
instance ZeroTestable (t m r) => ZeroTestable.C (CycRep t C m r) where
isZero (CRTC _ v) = isZero v
{-# INLINABLE isZero #-}
instance (TensorPowDec t r, Fact m) => Additive.C (CycRep t P m r) where
{-# SPECIALIZE instance (TensorPowDec t Int64, Fact m) => Additive.C (CycRep t P m Int64) #-}
{-# SPECIALIZE instance (TensorPowDec t Double, Fact m) => Additive.C (CycRep t P m Double) #-}
{-# SPECIALIZE instance (TensorPowDec t (ZqBasic q Int64), Fact m) => Additive.C (CycRep t P m (ZqBasic q Int64)) #-}
zero = Pow $ T.scalarPow zero
(Pow v1) + (Pow v2) = Pow $ zipWithI (+) v1 v2
(Pow v1) - (Pow v2) = Pow $ zipWithI (-) v1 v2
negate (Pow v) = Pow $ fmapI negate v
{-# INLINABLE zero #-}
{-# INLINABLE (+) #-}
{-# INLINABLE (-) #-}
{-# INLINABLE negate #-}
instance (TensorPowDec t r, Fact m) => Additive.C (CycRep t D m r) where
{-# SPECIALIZE instance (TensorPowDec t Int64, Fact m) => Additive.C (CycRep t D m Int64) #-}
{-# SPECIALIZE instance (TensorPowDec t Double, Fact m) => Additive.C (CycRep t D m Double) #-}
{-# SPECIALIZE instance (TensorPowDec t (ZqBasic q Int64), Fact m) => Additive.C (CycRep t D m (ZqBasic q Int64)) #-}
zero = Dec $ T.scalarPow zero
(Dec v1) + (Dec v2) = Dec $ zipWithI (+) v1 v2
(Dec v1) - (Dec v2) = Dec $ zipWithI (-) v1 v2
negate (Dec v) = Dec $ fmapI negate v
{-# INLINABLE zero #-}
{-# INLINABLE (+) #-}
{-# INLINABLE (-) #-}
{-# INLINABLE negate #-}
instance (Fact m, CRTElt t r) => Additive.C (CycRepEC t m r) where
{-# SPECIALIZE instance (Fact m, CRTElt t Int64) => Additive.C (CycRepEC t m Int64) #-}
{-# SPECIALIZE instance (Fact m, CRTElt t Double) => Additive.C (CycRepEC t m Double) #-}
{-# SPECIALIZE instance (Fact m, CRTElt t (ZqBasic q Int64)) => Additive.C (CycRepEC t m (ZqBasic q Int64)) #-}
zero = scalarCRT zero
(Right (CRTC s v1)) + (Right (CRTC _ v2)) = Right $ CRTC s $ zipWithI (+) v1 v2
(Left (CRTE s v1)) + (Left (CRTE _ v2)) = Left $ CRTE s $ zipWithI (+) v1 v2
_ + _ = error "CycRep (+) internal error: mixed CRTC/CRTE"
(Right (CRTC s v1)) - (Right (CRTC _ v2)) = Right $ CRTC s $ zipWithI (-) v1 v2
(Left (CRTE s v1)) - (Left (CRTE _ v2)) = Left $ CRTE s $ zipWithI (-) v1 v2
_ - _ = error "CycRep (-) internal error: mixed CRTC/CRTE"
negate (Right (CRTC s v)) = Right $ CRTC s $ fmapI negate v
negate (Left (CRTE s v)) = Left $ CRTE s $ fmapI negate v
{-# INLINABLE zero #-}
{-# INLINABLE (+) #-}
{-# INLINABLE (-) #-}
{-# INLINABLE negate #-}
instance (Fact m, CRTElt t r) => Ring.C (CycRepEC t m r) where
{-# SPECIALIZE instance (Fact m, CRTElt t Int64) => Ring.C (CycRepEC t m Int64) #-}
{-# SPECIALIZE instance (Fact m, CRTElt t Double) => Ring.C (CycRepEC t m Double) #-}
{-# SPECIALIZE instance (Fact m, CRTElt t (ZqBasic q Int64)) => Ring.C (CycRepEC t m (ZqBasic q Int64)) #-}
one = scalarCRT one
fromInteger c = scalarCRT $ fromInteger c
(Right (CRTC s v1)) * (Right (CRTC _ v2)) = Right $ CRTC s $ zipWithI (*) v1 v2
(Left (CRTE s v1)) * (Left (CRTE _ v2)) = Left $ CRTE s $ zipWithI (*) v1 v2
_ * _ = error "CycRep internal error: mixed CRTC/CRTE"
{-# INLINABLE one #-}
{-# INLINABLE fromInteger #-}
{-# INLINABLE (*) #-}
instance (Ring r, TensorPowDec t r, Fact m) => Module.C r (CycRep t P m r) where
{-# SPECIALIZE instance (Fact m, TensorPowDec t Int64) => Module.C Int64 (CycRep t P m Int64) #-}
{-# SPECIALIZE instance (Fact m, TensorPowDec t Double) => Module.C Double (CycRep t P m Double) #-}
{-# SPECIALIZE instance (Fact m, TensorPowDec t (ZqBasic q Int64), Reflects q Int64) => Module.C (ZqBasic q Int64) (CycRep t P m (ZqBasic q Int64)) #-}
r *> (Pow v) = Pow $ fmapI (r *) v
{-# INLINABLE (*>) #-}
instance (Ring r, TensorPowDec t r, Fact m) => Module.C r (CycRep t D m r) where
{-# SPECIALIZE instance (Fact m, TensorPowDec t Int64) => Module.C Int64 (CycRep t D m Int64) #-}
{-# SPECIALIZE instance (Fact m, TensorPowDec t Double) => Module.C Double (CycRep t D m Double) #-}
{-# SPECIALIZE instance (Fact m, TensorPowDec t (ZqBasic q Int64), Reflects q Int64) => Module.C (ZqBasic q Int64) (CycRep t D m (ZqBasic q Int64)) #-}
r *> (Dec v) = Dec $ fmapI (r *) v
{-# INLINABLE (*>) #-}
instance (CRTElt t r, Fact m) => Module.C r (CycRepEC t m r) where
{-# SPECIALIZE instance (CRTElt t Int64, Fact m) => Module.C Int64 (CycRepEC t m Int64) #-}
{-# SPECIALIZE instance (CRTElt t Double, Fact m) => Module.C Double (CycRepEC t m Double) #-}
{-# SPECIALIZE instance (CRTElt t (ZqBasic q Int64), Fact m) => Module.C (ZqBasic q Int64) (CycRepEC t m (ZqBasic q Int64)) #-}
r *> (Right (CRTC s v)) = Right $ CRTC s $ fmapI (r *) v
r *> (Left (CRTE s v)) = Left $ CRTE s $ fmapI (toExt r *) v
{-# INLINABLE (*>) #-}
instance (GFCtx fp d, Fact m, TensorPowDec t fp, Module (GF fp d) (t m fp))
=> Module.C (GF fp d) (CycRep t P m fp) where
r *> (Pow v) = Pow $ r LP.*> v
instance (Fact m, Reduce a b, IFunctor t, IFElt t a, IFElt t b)
=> Reduce (CycRep t P m a) (CycRep t P m b) where
{-# SPECIALIZE instance (Fact m, Reflects q Int64, IFunctor t, IFElt t Int64, IFElt t (ZqBasic q Int64)) => Reduce (CycRep t P m Int64) (CycRep t P m (ZqBasic q Int64)) #-}
reduce (Pow v) = Pow $ fmapI reduce v
{-# INLINABLE reduce #-}
instance (Fact m, Reduce a b, IFunctor t, IFElt t a, IFElt t b)
=> Reduce (CycRep t D m a) (CycRep t D m b) where
{-# SPECIALIZE instance (Fact m, Reflects q Int64, IFunctor t, IFElt t Int64, IFElt t (ZqBasic q Int64)) => Reduce (CycRep t D m Int64) (CycRep t D m (ZqBasic q Int64)) #-}
reduce (Dec v) = Dec $ fmapI reduce v
{-# INLINABLE reduce #-}
type instance LiftOf (CycRep t P m r) = CycRep t P m (LiftOf r)
type instance LiftOf (CycRep t D m r) = CycRep t D m (LiftOf r)
instance (Fact m, Lift' r, IFunctor t, IFElt t r, IFElt t (LiftOf r))
=> Lift' (CycRep t P m r) where
{-# SPECIALIZE instance (Fact m, Reflects q Int64, IFunctor t, IFElt t Int64, IFElt t (ZqBasic q Int64)) => Lift' (CycRep t P m (ZqBasic q Int64)) #-}
lift (Pow v) = Pow $ fmapI lift v
{-# INLINABLE lift #-}
instance (Lift' r, IFunctor t, IFElt t r, IFElt t (LiftOf r), Fact m)
=> Lift' (CycRep t D m r) where
{-# SPECIALIZE instance (Fact m, Reflects q Int64, IFunctor t, IFElt t Int64, IFElt t (ZqBasic q Int64)) => Lift' (CycRep t D m (ZqBasic q Int64)) #-}
lift (Dec v) = Dec $ fmapI lift v
{-# INLINABLE lift #-}
instance (Rescale a b, TensorPowDec t a, TensorPowDec t b, Fact m)
=> Rescale (CycRep t P m a) (CycRep t P m b) where
rescale (Pow v) = Pow $ fmapI rescale v
{-# INLINABLE rescale #-}
instance (Rescale a b, TensorPowDec t a, TensorPowDec t b, Fact m)
=> Rescale (CycRep t D m a) (CycRep t D m b) where
rescale (Dec v) = Dec $ fmapI rescale v
{-# INLINABLE rescale #-}
mulGPow :: (Fact m, TensorG t r) => CycRep t P m r -> CycRep t P m r
{-# INLINABLE mulGPow #-}
mulGPow (Pow v) = Pow $ T.mulGPow v
mulGDec :: (Fact m, TensorG t r) => CycRep t D m r -> CycRep t D m r
{-# INLINABLE mulGDec #-}
mulGDec (Dec v) = Dec $ T.mulGDec v
mulGCRTC :: (Fact m, TensorCRT t Maybe r)
=> CycRep t C m r -> CycRep t C m r
{-# INLINABLE mulGCRTC #-}
mulGCRTC (CRTC s v) = CRTC s $ mulGCRTCS s v
divGPow :: (Fact m, TensorG t r) => CycRep t P m r -> Maybe (CycRep t P m r)
{-# INLINABLE divGPow #-}
divGPow (Pow v) = Pow <$> T.divGPow v
divGDec :: (Fact m, TensorG t r) => CycRep t D m r -> Maybe (CycRep t D m r)
{-# INLINABLE divGDec #-}
divGDec (Dec v) = Dec <$> T.divGDec v
divGCRTC :: (Fact m, CRTElt t r) => CycRep t C m r -> CycRep t C m r
{-# INLINE divGCRTC #-}
divGCRTC (CRTC s v) = CRTC s $ divGCRTCS s v
gSqNormDec :: (TensorGSqNorm t r, Fact m) => CycRep t D m r -> r
{-# INLINABLE gSqNormDec #-}
gSqNormDec (Dec v) = T.gSqNormDec v
tweakedGaussian :: (TensorGaussian t q, MonadRandom rnd, Fact m, ToRational v)
=> v -> rnd (CycRep t D m q)
{-# INLINABLE tweakedGaussian #-}
tweakedGaussian = fmap Dec . tweakedGaussianDec
roundedGaussian :: forall v rnd t m z .
(TensorGaussian t Double, IFElt t Double, IFunctor t, ToInteger z,
IFElt t z, Fact m, ToRational v, MonadRandom rnd)
=> v -> rnd (CycRep t D m z)
{-# INLINABLE roundedGaussian #-}
roundedGaussian svar =
Dec . fmapI (roundMult one) <$> (tweakedGaussianDec svar :: rnd (t m Double))
cosetGaussian :: forall t m zp z v rnd .
(TensorGaussian t Double, IFElt t Double, IFunctor t, Lift zp z, Mod zp,
z ~ ModRep zp, IFElt t zp, IFElt t z, Fact m, ToRational v, MonadRandom rnd)
=> v -> CycRep t D m zp -> rnd (CycRep t D m z)
{-# INLINABLE cosetGaussian #-}
cosetGaussian =
let pval = fromIntegral $ modulus @zp
in \ svar (Dec c) ->
Dec . zipWithI roundCoset c <$>
(tweakedGaussianDec (svar*pval*pval) :: rnd (t m Double))
embedPow :: (TensorPowDec t r, m `Divides` m') => CycRep t P m r -> CycRep t P m' r
embedPow (Pow v) = Pow $ T.embedPow v
{-# INLINABLE embedPow #-}
embedCRTC :: (m `Divides` m', CRTElt t r)
=> CycRep t C m r -> Either (CycRep t P m' r) (CycRep t C m' r)
{-# INLINABLE embedCRTC #-}
embedCRTC x@(CRTC s v) =
case crtSentinel of
Left _ -> Left $ embedPow $ toPow x
Right s' -> Right $ CRTC s' $ embedCRTCS s s' v
embedCRTE :: forall m m' t r . (m `Divides` m', CRTElt t r)
=> CycRep t E m r -> Either (CycRep t P m' r) (CycRep t E m' r)
{-# INLINABLE embedCRTE #-}
embedCRTE x@(CRTE _ v) =
case crtSentinel of
Left s -> Right $ CRTE s $ runIdentity T.embedCRT v
Right _ -> Left $ embedPow $ toPow x
twacePow :: (TensorPowDec t r, m `Divides` m')
=> CycRep t P m' r -> CycRep t P m r
{-# INLINABLE twacePow #-}
twacePow (Pow v) = Pow $ twacePowDec v
twaceDec :: (TensorPowDec t r, m `Divides` m') => CycRep t D m' r -> CycRep t D m r
{-# INLINABLE twaceDec #-}
twaceDec (Dec v) = Dec $ twacePowDec v
twaceCRTC :: (m `Divides` m', CRTElt t r) => CycRep t C m' r -> CycRepPC t m r
{-# INLINE twaceCRTC #-}
twaceCRTC x@(CRTC s' v) =
case crtSentinel of
Left _ -> Left $ twacePow $ toPow x
Right s -> Right $ CRTC s $ twaceCRTCS s' s v
twaceCRTE :: forall t m m' r . (m `Divides` m', CRTElt t r)
=> CycRep t E m' r -> Either (CycRep t P m r) (CycRep t E m r)
{-# INLINABLE twaceCRTE #-}
twaceCRTE x@(CRTE _ v) =
case crtSentinel of
Left s -> Right $ CRTE s $ runIdentity T.twaceCRT v
Right _ -> Left $ twacePow $ toPow x
coeffsPow :: (TensorPowDec t r, m `Divides` m') => CycRep t P m' r -> [CycRep t P m r]
{-# INLINABLE coeffsPow #-}
coeffsPow (Pow v) = Pow <$> coeffs v
coeffsDec :: (TensorPowDec t r, m `Divides` m') => CycRep t D m' r -> [CycRep t D m r]
{-# INLINABLE coeffsDec #-}
coeffsDec (Dec v) = Dec <$> coeffs v
powBasis :: forall m m' t r .
(TensorPowDec t r, m `Divides` m') => [CycRep t P m' r]
{-# INLINABLE powBasis #-}
powBasis = fmap Pow $ untag $ powBasisPow @t @r @m
crtSet :: forall m m' pp p mbar m'bar t z zpp .
(m `Divides` m', p ~ PrimePP pp, mbar ~ PFree p m, m'bar ~ PFree p m',
PPow pp, Prime p, zpp ~ ZqBasic pp z,
ToInteger z, CRTElt t zpp, TensorCRTSet t (ZqBasic p z))
=> [CycRep t P m' (ZqBasic pp z)]
{-# INLINABLE crtSet #-}
crtSet =
let (p,e) = ppPPow @pp
expon :: (Fact m'bar, ToPowDec t rep (ZqBasic pp z))
=> Int -> CycRep t rep m'bar zpp -> CycRep t P m'bar zpp
expon 1 = toPow
expon e' = toPowCE . (^p) . toCRT . expon (e'-1)
in embedPow . expon e . Dec . fmapI (ZqB . unZqB) <$>
(untag $ crtSetDec @t @_ @mbar :: [t m'bar (ZqBasic p z)])
\\ pFreeDivides @p @m @m' \\ pSplitTheorems @p @m \\ pSplitTheorems @p @m'
class ToPowDec t rep r where
toPow :: (Fact m) => CycRep t rep m r -> CycRep t P m r
toDec :: (Fact m) => CycRep t rep m r -> CycRep t D m r
class ToCRT t rep r where
toCRT :: (Fact m) => CycRep t rep m r -> Either (CycRep t E m r) (CycRep t C m r)
instance TensorPowDec t r => ToPowDec t P r where
toPow = id
toDec (Pow v) = Dec $ powToDec v
{-# INLINABLE toPow #-}
{-# INLINABLE toDec #-}
instance CRTElt t r => ToCRT t P r where
toCRT (Pow v) = case crtSentinel of
Right s -> Right $ CRTC s $ crtCS s v
Left s -> Left $ CRTE s $ runIdentity crt $ fmapI toExt v
{-# INLINABLE toCRT #-}
instance TensorPowDec t r => ToPowDec t D r where
toPow (Dec v) = Pow $ decToPow v
toDec = id
{-# INLINABLE toPow #-}
{-# INLINABLE toDec #-}
instance CRTElt t r => ToCRT t D r where
toCRT = toCRT . toPow
{-# INLINABLE toCRT #-}
instance CRTElt t r => ToPowDec t C r where
toPow (CRTC s v) = Pow $ crtInvCS s v
toDec = toDec . toPow
{-# INLINABLE toPow #-}
{-# INLINABLE toDec #-}
instance ToCRT t C r where
toCRT = Right
{-# INLINABLE toCRT #-}
instance CRTElt t r => ToPowDec t E r where
toPow (CRTE _ v) = Pow $ fmapI fromExt $ runIdentity crtInv v
toDec = toDec . toPow
{-# INLINABLE toPow #-}
{-# INLINABLE toDec #-}
instance ToCRT t E r where
toCRT = Left
{-# INLINABLE toCRT #-}
toPowCE :: (Fact m, CRTElt t r) => CycRepEC t m r -> CycRep t P m r
{-# INLINABLE toPowCE #-}
toPowCE (Left u) = toPow u
toPowCE (Right u) = toPow u
instance IFunctor t => IFunctor (CycRep t P) where
type IFElt (CycRep t P) a = IFElt t a
fmapI f (Pow v) = Pow $ fmapI f v
zipWithI f (Pow v) (Pow w) = Pow $ zipWithI f v w
instance IFunctor t => IFunctor (CycRep t D) where
type IFElt (CycRep t D) a = IFElt t a
fmapI f (Dec v) = Dec $ fmapI f v
zipWithI f (Dec v) (Dec w) = Dec $ zipWithI f v w
instance Functor (t m) => Functor (CycRep t P m) where
{-# INLINABLE fmap #-}
fmap f (Pow x) = Pow $ f <$> x
instance Functor (t m) => Functor (CycRep t D m) where
{-# INLINABLE fmap #-}
fmap f (Dec x) = Dec $ f <$> x
instance Applicative (t m) => Applicative (CycRep t P m) where
pure = Pow . pure
(Pow f) <*> (Pow v) = Pow $ f <*> v
{-# INLINABLE pure #-}
{-# INLINABLE (<*>) #-}
instance Applicative (t m) => Applicative (CycRep t D m) where
pure = Dec . pure
(Dec f) <*> (Dec v) = Dec $ f <*> v
{-# INLINABLE pure #-}
{-# INLINABLE (<*>) #-}
instance Foldable (t m) => Foldable (CycRep t P m) where
foldr f z (Pow x) = foldr f z x
instance Foldable (t m) => Foldable (CycRep t D m) where
foldr f z (Dec x) = foldr f z x
instance Foldable (t m) => Foldable (CycRep t C m) where
foldr f b (CRTC _ v) = foldr f b v
instance Traversable (t m) => Traversable (CycRep t P m) where
{-# INLINABLE traverse #-}
traverse f (Pow v) = Pow <$> traverse f v
instance Traversable (t m) => Traversable (CycRep t D m) where
{-# INLINABLE traverse #-}
traverse f (Dec v) = Dec <$> traverse f v
instance (Random (t m r)) => Random (CycRep t P m r) where
random g = let (v,g') = random g
in (Pow v, g')
randomR _ = error "randomR non-sensical for CycRep"
instance (Random (t m r)) => Random (CycRep t D m r) where
random g = let (v,g') = random g
in (Dec v, g')
randomR _ = error "randomR non-sensical for CycRep"
instance (Random (t m r), Fact m, TensorCRT t Maybe r)
=> Random (CycRepPC t m r) where
random = let cons = case crtSentinel of
Left _ -> Left . Pow
Right s -> Right . CRTC s
in \g -> let (v,g') = random g
in (cons v, g')
randomR _ = error "randomR non-sensical for CycRep"
instance (Show (t m r)) => Show (CycRep t P m r) where
show (Pow x) = "CycRep.Pow " ++ show x
instance (Show (t m r)) => Show (CycRep t D m r) where
show (Dec x) = "CycRep.Dec " ++ show x
instance (Show (t m r)) => Show (CycRep t C m r) where
show (CRTC _ x) = "CycRep.CRTC " ++ show x
instance (Show (t m (CRTExt r))) => Show (CycRep t E m r) where
show (CRTE _ x) = "CycRep.CRTE " ++ show x
instance (NFData (t m r)) => NFData (CycRep t P m r) where
rnf (Pow x) = rnf x
instance (NFData (t m r)) => NFData (CycRep t D m r) where
rnf (Dec x) = rnf x
instance (NFData (t m r)) => NFData (CycRep t C m r) where
rnf (CRTC _ x) = rnf x
instance (NFData (t m (CRTExt r))) => NFData (CycRep t E m r) where
rnf (CRTE _ x) = rnf x
instance (Protoable (t m r)) => Protoable (CycRep t D m r) where
type ProtoType (CycRep t D m r) = ProtoType (t m r)
toProto (Dec t) = toProto t
fromProto t = Dec <$> fromProto t