{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances, KindSignatures, MultiParamTypeClasses, NoImplicitPrelude, PolyKinds, ScopedTypeVariables, UndecidableInstances #-} -- | Generic interface for reflecting types to values. module Crypto.Lol.Reflects ( Reflects(..) ) where import Algebra.ToInteger as ToInteger import NumericPrelude import Crypto.Lol.Factored import Control.Applicative import Data.Functor.Trans.Tagged import Data.Proxy import Data.Reflection import GHC.TypeLits as TL -- | Reflection without fundep, and with tagged value. Intended only -- for low-level code; build specialized wrappers around it for -- specific functionality. class Reflects a i where -- | Reflect the value assiated with the type @a@. value :: Tagged a i instance (KnownNat a, ToInteger.C i) => Reflects (a :: TL.Nat) i where value = tag $ fromIntegral $ natVal (Proxy::Proxy a) {- instance (PosC a, ToInteger.C i) => Reflects a i where value = tag $ posToInt $ fromSing (sing :: Sing a) instance (BinC a, ToInteger.C i) => Reflects a i where value = tag $ binToInt $ fromSing (sing :: Sing a) -} -- CJP: need reflections for Prime and PrimePower types because we use -- them with ZqBasic instance (Prim p, ToInteger.C i) => Reflects p i where value = fromIntegral <$> valuePrime instance (PPow pp, ToInteger.C i) => Reflects pp i where value = fromIntegral <$> valuePPow -- CJP: need this for Types.ZmStar, where we use ZqBasic m Int instance (Fact m, ToInteger.C i) => Reflects m i where value = fromIntegral <$> valueFact instance {-# OVERLAPS #-} (Reifies rei a) => Reflects (rei :: *) a where value = tag $ reflect (Proxy::Proxy rei)