Self optimzing pair types.
This library statically adapts the polymorphic container representation of tuples to specific, more efficient representations, when instantiated with particular monomorphic types. It does this via an associated more efficient data type for each pair of elements you wish to store in your container.
That is, instead of representing '(Int,Char)' as:
(,) / \ I# 3# C# x#
A self-optimizing pair will unpack the constructors, yielding this data representation:
PairIntChar 3# x#
Saving two indirections. The resulting structure should be both more time and space efficient than the generic polymorphic container it is derived from. For example, adaptive pairs use 8 bytes to store an Int and Char pair, while a lazy pair uses 24 bytes.
> Prelude Size> unsafeSizeof ((42, 'x') :: (Int,Char)) > 24
Prelude Size> unsafeSizeof (pair 42 'x' :: Pair Int Char) > 8
You can inspect the size and layout of your adaptive structures using two scripts, one for measuring the size of a closure, described in http://ghcmutterings.wordpress.com/2009/02/, and vacuum-cairo, for rendering the heap structure explicitly http://hackage.haskell.org/cgi-bin/hackage-scripts/package/vacuum-cairo
Types that instantiate the
Adapt class will self-adapt this way.
Self adaptive polymorphic containers are able to unpack their components, something not possible with, for example, strict polymorphic containers.
- class AdaptPair a b where
- pair :: AdaptPair a b => a -> b -> Pair a b
- uncurry :: AdaptPair a b => (a -> b -> c) -> Pair a b -> c
- fromPair :: AdaptPair a b => Pair a b -> (a, b)
- toPair :: AdaptPair a b => (a, b) -> Pair a b
Representation-improving polymorphic tuples.
Extract the first component of a pair.
Extract the second component of a pair.
curry converts an uncurried function to a curried function.
uncurry converts a curried function to a function on pairs.
Convert an adaptive pair to a regular polymorphic tuple