{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE TypeOperators #-}
module Data.AbstractSize
( HasTypeReps,
typeReps,
abstractSize,
AccountingMap,
Size,
)
where
import Cardano.Crypto.DSIGN.Class (SignedDSIGN (SignedDSIGN), VerKeyDSIGN)
import Cardano.Crypto.DSIGN.Mock (MockDSIGN, SigDSIGN (SigMockDSIGN))
import Cardano.Crypto.Hash (Hash, hashToBytes)
import Cardano.Crypto.Hash.Short (ShortHash)
import qualified Crypto.Hash as Crypto
import qualified Data.ByteString as BS
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Sequence (Seq, empty, (<|), (><))
import qualified Data.Sequence as Seq
import Data.Set (Set)
import Data.Typeable (TypeRep, Typeable, typeOf)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Generics
( Generic,
K1 (K1),
M1 (M1),
Rep,
U1 (U1),
from,
(:*:) ((:*:)),
(:+:) (L1, R1),
)
import GHC.Natural (Natural)
abstractSize :: HasTypeReps a => AccountingMap -> a -> Size
abstractSize :: AccountingMap -> a -> Size
abstractSize AccountingMap
m a
a = Seq Size -> Size
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (Seq Size -> Size) -> Seq Size -> Size
forall a b. (a -> b) -> a -> b
$ (TypeRep -> Size) -> Seq TypeRep -> Seq Size
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TypeRep -> Size
cost Seq TypeRep
trs
where
trs :: Seq TypeRep
trs = a -> Seq TypeRep
forall a. HasTypeReps a => a -> Seq TypeRep
typeReps a
a
cost :: TypeRep -> Size
cost TypeRep
t = Size -> TypeRep -> AccountingMap -> Size
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Size
0 TypeRep
t AccountingMap
m
type Size = Int
type AccountingMap = Map TypeRep Size
class HasTypeReps a where
typeReps :: a -> Seq TypeRep
default typeReps ::
( Generic a,
GHasTypeReps (Rep a),
Typeable a
) =>
a ->
Seq TypeRep
typeReps a
a = a -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf a
a TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. a -> Seq a -> Seq a
<| Rep a Any -> Seq TypeRep
forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps (a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from a
a)
class GHasTypeReps f where
gTypeReps :: f a -> Seq TypeRep
instance GHasTypeReps U1 where
gTypeReps :: U1 a -> Seq TypeRep
gTypeReps U1 a
U1 = Seq TypeRep
forall a. Seq a
empty
instance (GHasTypeReps a, GHasTypeReps b) => GHasTypeReps (a :*: b) where
gTypeReps :: (:*:) a b a -> Seq TypeRep
gTypeReps (a a
a :*: b a
b) = a a -> Seq TypeRep
forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps a a
a Seq TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. Seq a -> Seq a -> Seq a
>< b a -> Seq TypeRep
forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps b a
b
instance (GHasTypeReps a, GHasTypeReps b) => GHasTypeReps (a :+: b) where
gTypeReps :: (:+:) a b a -> Seq TypeRep
gTypeReps (L1 a a
a) = a a -> Seq TypeRep
forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps a a
a
gTypeReps (R1 b a
b) = b a -> Seq TypeRep
forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps b a
b
instance (GHasTypeReps a) => GHasTypeReps (M1 i c a) where
gTypeReps :: M1 i c a a -> Seq TypeRep
gTypeReps (M1 a a
x) = a a -> Seq TypeRep
forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps a a
x
instance (HasTypeReps a) => GHasTypeReps (K1 i a) where
gTypeReps :: K1 i a a -> Seq TypeRep
gTypeReps (K1 a
x) = a -> Seq TypeRep
forall a. HasTypeReps a => a -> Seq TypeRep
typeReps a
x
instance (Typeable a, HasTypeReps a) => HasTypeReps (Maybe a) where
typeReps :: Maybe a -> Seq TypeRep
typeReps Maybe a
x = Maybe a -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Maybe a
x TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. a -> Seq a -> Seq a
<| Seq TypeRep -> (a -> Seq TypeRep) -> Maybe a -> Seq TypeRep
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] a -> Seq TypeRep
forall a. HasTypeReps a => a -> Seq TypeRep
typeReps Maybe a
x
instance (Typeable a, HasTypeReps a) => HasTypeReps [a] where
typeReps :: [a] -> Seq TypeRep
typeReps [a]
xs = [a] -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf [a]
xs TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. a -> Seq a -> Seq a
<| (a -> Seq TypeRep) -> [a] -> Seq TypeRep
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> Seq TypeRep
forall a. HasTypeReps a => a -> Seq TypeRep
typeReps [a]
xs
instance (Typeable a, HasTypeReps a) => HasTypeReps (Set a) where
typeReps :: Set a -> Seq TypeRep
typeReps Set a
xs = Set a -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Set a
xs TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. a -> Seq a -> Seq a
<| (a -> Seq TypeRep) -> Set a -> Seq TypeRep
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> Seq TypeRep
forall a. HasTypeReps a => a -> Seq TypeRep
typeReps Set a
xs
instance
( Typeable a,
Typeable b,
HasTypeReps a,
HasTypeReps b
) =>
HasTypeReps (a, b)
where
typeReps :: (a, b) -> Seq TypeRep
typeReps t :: (a, b)
t@(a
a, b
b) = (a, b) -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf (a, b)
t TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. a -> Seq a -> Seq a
<| (a -> Seq TypeRep
forall a. HasTypeReps a => a -> Seq TypeRep
typeReps a
a Seq TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. Seq a -> Seq a -> Seq a
>< b -> Seq TypeRep
forall a. HasTypeReps a => a -> Seq TypeRep
typeReps b
b)
instance HasTypeReps Bool where
typeReps :: Bool -> Seq TypeRep
typeReps Bool
x = [Bool -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Bool
x]
instance HasTypeReps Char where
typeReps :: Char -> Seq TypeRep
typeReps Char
x = [Char -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Char
x]
instance HasTypeReps Int where
typeReps :: Size -> Seq TypeRep
typeReps Size
x = [Size -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Size
x]
instance HasTypeReps Integer where
typeReps :: Integer -> Seq TypeRep
typeReps Integer
x = [Integer -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Integer
x]
instance HasTypeReps Double where
typeReps :: Double -> Seq TypeRep
typeReps Double
x = [Double -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Double
x]
instance HasTypeReps Natural where
typeReps :: Natural -> Seq TypeRep
typeReps Natural
x = [Natural -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Natural
x]
instance HasTypeReps Word where
typeReps :: Word -> Seq TypeRep
typeReps Word
x = [Word -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Word
x]
instance HasTypeReps Word8 where
typeReps :: Word8 -> Seq TypeRep
typeReps Word8
x = [Word8 -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Word8
x]
instance HasTypeReps Word16 where
typeReps :: Word16 -> Seq TypeRep
typeReps Word16
x = [Word16 -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Word16
x]
instance HasTypeReps Word32 where
typeReps :: Word32 -> Seq TypeRep
typeReps Word32
x = [Word32 -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Word32
x]
instance HasTypeReps Word64 where
typeReps :: Word64 -> Seq TypeRep
typeReps Word64
x = [Word64 -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Word64
x]
instance HasTypeReps (Crypto.Digest Crypto.SHA256) where
typeReps :: Digest SHA256 -> Seq TypeRep
typeReps Digest SHA256
x = [Digest SHA256 -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Digest SHA256
x]
instance HasTypeReps ShortHash where
typeReps :: ShortHash -> Seq TypeRep
typeReps ShortHash
x = [ShortHash -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf ShortHash
x]
instance Typeable a => HasTypeReps (Hash ShortHash a) where
typeReps :: Hash ShortHash a -> Seq TypeRep
typeReps Hash ShortHash a
x = [Hash ShortHash a -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Hash ShortHash a
x]
instance HasTypeReps (SignedDSIGN MockDSIGN a) where
typeReps :: SignedDSIGN MockDSIGN a -> Seq TypeRep
typeReps (SignedDSIGN (SigMockDSIGN h i)) =
Word64 -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf Word64
i TypeRep -> Seq TypeRep -> Seq TypeRep
forall a. a -> Seq a -> Seq a
<| Size -> TypeRep -> Seq TypeRep
forall a. Size -> a -> Seq a
Seq.replicate (ByteString -> Size
BS.length (Hash ShortHash () -> ByteString
forall h a. Hash h a -> ByteString
hashToBytes Hash ShortHash ()
h)) (Char -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf (Char
forall a. HasCallStack => a
undefined :: Char))
instance HasTypeReps (VerKeyDSIGN MockDSIGN) where
typeReps :: VerKeyDSIGN MockDSIGN -> Seq TypeRep
typeReps VerKeyDSIGN MockDSIGN
_ = [Size -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf (Size
forall a. HasCallStack => a
undefined :: Int)]