{-| Module : Crypto.Lol.Reflects Description : Generic interface for reflecting types to values. Copyright : (c) Eric Crockett, 2011-2017 Chris Peikert, 2011-2017 License : GPL-3 Maintainer : ecrockett0@email.com Stability : experimental Portability : POSIX Generic interface for reflecting types to values. -} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE UndecidableInstances #-} module Crypto.Lol.Reflects ( Reflects(..) ) where import Algebra.Ring as Ring import Algebra.ToInteger as ToInteger import NumericPrelude import Crypto.Lol.Factored import Data.Proxy import Data.Reflection import Data.Singletons 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 :: i instance (KnownNat a, Ring.C i) => Reflects (a :: TL.Nat) i where value = fromIntegral $ natVal (Proxy::Proxy a) instance (PosC a, ToInteger.C i) => Reflects a i where value = posToInt $ fromSing (sing :: Sing a) instance (BinC a, ToInteger.C i) => Reflects a i where value = binToInt $ fromSing (sing :: Sing a) instance (Prime p, ToInteger.C i) => Reflects p i where value = fromIntegral $ valuePrime @p instance (PPow pp, ToInteger.C i) => Reflects pp i where value = fromIntegral $ valuePPow @pp instance (Fact m, ToInteger.C i) => Reflects m i where value = fromIntegral $ valueFact @m instance (Reifies q i, ToInteger.C i, Ring.C r) => Reflects (q :: *) r where value = fromIntegral $ reflect (Proxy::Proxy q)