Copyright | (C) Koz Ross 2019 |
---|---|
License | GPL version 3.0 or later |
Maintainer | koz.ross@retro-freedom.nz |
Stability | Experimental |
Portability | GHC only |
Safe Haskell | Trustworthy |
Language | Haskell2010 |
If a type a
is Finitary
, each inhabitant of a
has an index, which can
be represented as a byte string of a fixed length (as the number of indexes
is finite). Essentially, we can represent any value of a
as a fixed-length
string over an alphabet of cardinality \(256\). Based on this, we can derive
a Unbox
instance, representing a Vector
as a large byte string.
This also allows us to provide a Storable
instance for a
.
This encoding is fairly tight in terms of space use, especially for types whose cardinalities are large. Additionally, byte-access is considerably faster than bit-access on most architectures. If your types have large cardinalities, and minimal space use isn't a concern, this encoding is good.
Some architectures prefer whole-word access - on these, there can be some
overheads using this encoding. Additionally, the encoding and decoding step
for this encoding is longer than the one for Data.Finitary.PackWords. If
Cardinality a < Cardinality Word
, you should
consider a different encoding - in particular, check Data.Finitary.PackInto,
which is more flexible and faster, with greater control over space usage.
Documentation
data PackBytes (a :: Type) Source #
An opaque wrapper around a
, representing each value as a byte string.
Instances
pattern Packed :: forall (a :: Type). (Finitary a, 1 <= Cardinality a) => a -> PackBytes a Source #
To provide (something that resembles a) data constructor for PackBytes
, we
provide the following pattern. It can be used like any other data
constructor:
import Data.Finitary.PackBytes anInt :: PackBytes Int anInt = Packed 10 isPackedEven :: PackBytes Int -> Bool isPackedEven (Packed x) = even x
Every pattern match, and data constructor call, performs a
\(\Theta(\log_{256}(\texttt{Cardinality a}))\) encoding or decoding of a
.
Use with this in mind.