{-# 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 :: forall a. HasTypeReps a => AccountingMap -> a -> Size
abstractSize AccountingMap
m a
a = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TypeRep -> Size
cost Seq TypeRep
trs
where
trs :: Seq TypeRep
trs = forall a. HasTypeReps a => a -> Seq TypeRep
typeReps a
a
cost :: TypeRep -> Size
cost TypeRep
t = 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 = forall a. Typeable a => a -> TypeRep
typeOf a
a forall a. a -> Seq a -> Seq a
<| forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps (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 :: forall a. U1 a -> Seq TypeRep
gTypeReps U1 a
U1 = forall a. Seq a
empty
instance (GHasTypeReps a, GHasTypeReps b) => GHasTypeReps (a :*: b) where
gTypeReps :: forall a. (:*:) a b a -> Seq TypeRep
gTypeReps (a a
a :*: b a
b) = forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps a a
a forall a. Seq a -> Seq a -> Seq a
>< forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps b a
b
instance (GHasTypeReps a, GHasTypeReps b) => GHasTypeReps (a :+: b) where
gTypeReps :: forall a. (:+:) a b a -> Seq TypeRep
gTypeReps (L1 a a
a) = forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps a a
a
gTypeReps (R1 b a
b) = forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps b a
b
instance GHasTypeReps a => GHasTypeReps (M1 i c a) where
gTypeReps :: forall a. M1 i c a a -> Seq TypeRep
gTypeReps (M1 a a
x) = forall (f :: * -> *) a. GHasTypeReps f => f a -> Seq TypeRep
gTypeReps a a
x
instance HasTypeReps a => GHasTypeReps (K1 i a) where
gTypeReps :: forall a. K1 i a a -> Seq TypeRep
gTypeReps (K1 a
x) = 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 = forall a. Typeable a => a -> TypeRep
typeOf Maybe a
x forall a. a -> Seq a -> Seq a
<| forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] 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 = forall a. Typeable a => a -> TypeRep
typeOf [a]
xs forall a. a -> Seq a -> Seq a
<| forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap 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 = forall a. Typeable a => a -> TypeRep
typeOf Set a
xs forall a. a -> Seq a -> Seq a
<| forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap 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) = forall a. Typeable a => a -> TypeRep
typeOf (a, b)
t forall a. a -> Seq a -> Seq a
<| (forall a. HasTypeReps a => a -> Seq TypeRep
typeReps a
a forall a. Seq a -> Seq a -> Seq a
>< forall a. HasTypeReps a => a -> Seq TypeRep
typeReps b
b)
instance HasTypeReps Bool where
typeReps :: Bool -> Seq TypeRep
typeReps Bool
x = [forall a. Typeable a => a -> TypeRep
typeOf Bool
x]
instance HasTypeReps Char where
typeReps :: Char -> Seq TypeRep
typeReps Char
x = [forall a. Typeable a => a -> TypeRep
typeOf Char
x]
instance HasTypeReps Int where
typeReps :: Size -> Seq TypeRep
typeReps Size
x = [forall a. Typeable a => a -> TypeRep
typeOf Size
x]
instance HasTypeReps Integer where
typeReps :: Integer -> Seq TypeRep
typeReps Integer
x = [forall a. Typeable a => a -> TypeRep
typeOf Integer
x]
instance HasTypeReps Double where
typeReps :: Double -> Seq TypeRep
typeReps Double
x = [forall a. Typeable a => a -> TypeRep
typeOf Double
x]
instance HasTypeReps Natural where
typeReps :: Natural -> Seq TypeRep
typeReps Natural
x = [forall a. Typeable a => a -> TypeRep
typeOf Natural
x]
instance HasTypeReps Word where
typeReps :: Word -> Seq TypeRep
typeReps Word
x = [forall a. Typeable a => a -> TypeRep
typeOf Word
x]
instance HasTypeReps Word8 where
typeReps :: Word8 -> Seq TypeRep
typeReps Word8
x = [forall a. Typeable a => a -> TypeRep
typeOf Word8
x]
instance HasTypeReps Word16 where
typeReps :: Word16 -> Seq TypeRep
typeReps Word16
x = [forall a. Typeable a => a -> TypeRep
typeOf Word16
x]
instance HasTypeReps Word32 where
typeReps :: Word32 -> Seq TypeRep
typeReps Word32
x = [forall a. Typeable a => a -> TypeRep
typeOf Word32
x]
instance HasTypeReps Word64 where
typeReps :: Word64 -> Seq TypeRep
typeReps Word64
x = [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 = [forall a. Typeable a => a -> TypeRep
typeOf Digest SHA256
x]
instance HasTypeReps ShortHash where
typeReps :: ShortHash -> Seq TypeRep
typeReps ShortHash
x = [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 = [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 Hash ShortHash ()
h Word64
i)) =
forall a. Typeable a => a -> TypeRep
typeOf Word64
i forall a. a -> Seq a -> Seq a
<| forall a. Size -> a -> Seq a
Seq.replicate (ByteString -> Size
BS.length (forall h a. Hash h a -> ByteString
hashToBytes Hash ShortHash ()
h)) (forall a. Typeable a => a -> TypeRep
typeOf (forall a. HasCallStack => a
undefined :: Char))
instance HasTypeReps (VerKeyDSIGN MockDSIGN) where
typeReps :: VerKeyDSIGN MockDSIGN -> Seq TypeRep
typeReps VerKeyDSIGN MockDSIGN
_ = [forall a. Typeable a => a -> TypeRep
typeOf (forall a. HasCallStack => a
undefined :: Int)]