Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
An approach to computing the abstract size of data using TypeRep
.
Synopsis
- class HasTypeReps a
- typeReps ∷ HasTypeReps a ⇒ a → Seq TypeRep
- abstractSize ∷ HasTypeReps a ⇒ AccountingMap → a → Size
- type AccountingMap = Map TypeRep Size
- type Size = Int
Documentation
class HasTypeReps a Source #
The typeReps
function retrieves all the type representations found while
traversing the data given as parameter.
CAUTION: for newtypes, do not use 'deriving newtype (HasTypeReps)' to derive
instances, rather use 'deriving anyclass (HasTypeReps)'.
This is because we use these instances in abstractSize
, and for that
we prefer to have the newtype wrapper type available for "costing".
The difference between 'newtype' and anyclass
instances is as follows:
newtype Hash = Hash { unHash :: Int } deriving newtype (..., HasTypeReps) > typeReps someHash = Seq.fromList [Int] vs newtype Hash = Hash { unHash :: Int } deriving stock (...,Generics); deriving anyclass (HasTypeReps) > typeReps someHash = Seq.fromList [Hash, Int]
Examples:
>>>
typeReps "a"
fromList [[Char],Char]
>>>
typeReps "ab"
fromList [[Char],Char,Char]
>>>
typeReps ([] :: [Int])
fromList [[Int]]
>>>
:set -XDeriveGeneric
>>>
import GHC.Generics (Generic)
>>>
data Foo = Foo [Int] (Char, Char) deriving (Generic)
>>>
instance HasTypeReps Foo
>>>
typeReps $ Foo [1, 2] ('a', 'b')
fromList [Foo,[Int],Int,Int,(Char,Char),Char,Char]
Instances
typeReps ∷ HasTypeReps a ⇒ a → Seq TypeRep Source #
abstractSize ∷ HasTypeReps a ⇒ AccountingMap → a → Size Source #
abstractSize m a
computes the abstract size of a
, using the accounting
map m
. The map m
determines the abstract size of each TypeRep
contained in a
, and this function simply adds all the individual abstract
sizes. To be able to extract the type representations (TypeRep
s) inside
a
, we require it to be an instance of HasTypeReps
.
Examples:
>>>
:set -XOverloadedLists
>>>
import Data.Typeable (typeOf)
>>>
abstractSize [(typeOf (undefined:: Char), 10)] 'a'
10
>>>
abstractSize [(typeOf 'x', 10)] "hello"
50
>>>
abstractSize [(typeOf 'x', 10), (typeOf True, 100)] ("hello", False)
150
>>>
abstractSize [(typeOf (undefined :: [Int]), 6), (typeOf (1 :: Int), 1)] ([0, 1, 2, 3] :: [Int])
10
>>>
abstractSize [(typeOf (undefined :: [Int]), 3), (typeOf (1 :: Int), -1)] ([0, 1, 2] :: [Int])
0
type AccountingMap = Map TypeRep Size Source #