Safe Haskell | Trustworthy |
---|---|
Language | Haskell98 |
Serialization of compound data types (with class!). Also read and write methods' type class contexts are implemented with heterogeneous list constraints, making them sufficiently abstract. For every context FooCtx that a program uses, one has a constraint HasField ctx FooCtx, that allows one to find the context evidence in the concrete context.
The recursive function that is generally needed to traverse an inductive data type instance is
implemented in readOneLayer
. A bare-bones reader function is then let r = readOneLayer proxy r in r.
A poly-traversal is a function that is inserted into this recursive call chain. For instance,
cycReadCompoundData
is a poly-traversal implementing cycle detection for circular data dependencies,
but it leaves the programmer free to determine exactly how the layers are to be read.
The types of poly-traversals are found in PolyTraversal
and PolyTraversalW
.
Technically, the type of poly-traversals encompasses all co-recursive definitions at that type.
Well-founded recursion cannot be guaranteed owing to the cyclical nature of data structures.
If one needs recursion to be well-founded, one can use cycReadCompoundData
-- the well-foundedness
then follows from the finitude of the addresses.
- module Data.Columbia.SeekableStream
- module Data.Columbia.SeekableWriter
- module Data.Generics.SYB.WithClass.Instances
- module Data.Columbia.SeekableStream
- module Data.Columbia.SeekableWriter
- class Typeable t => RW t where
- data RWCtx a = RW a => RWCtx
- (#.) :: Data ctx t => PolyTraversal ctx m t -> (forall t2. Data ctx t2 => PolyTraversal ctx m t2) -> PolyTraversal ctx m t
- (##.) :: Data ctx t => PolyTraversalW ctx m t -> (forall t2. Data ctx t2 => PolyTraversalW ctx m t2) -> PolyTraversalW ctx m t
- fixT :: Data ctx t => Proxy ctx -> (forall t2. Data ctx t2 => PolyTraversal ctx m t2) -> ReaderT (SeekableStream m Word8) m t
- fixTW :: Data ctx t => Proxy ctx -> (forall t2. Data ctx t2 => PolyTraversalW ctx m t2) -> t -> ReaderT (SeekableWriter m Word8) m Word32
- typeCoerce :: (Typeable t, Data ctx t2) => PolyTraversal ctx m t -> (forall t3. Data ctx t3 => PolyTraversal ctx m t3) -> PolyTraversal ctx m t2
- class Typeable t => RW t where
- data RWCtx a = RW a => RWCtx
- type PolyTraversal ctx m d = Proxy ctx -> (forall a. Data ctx a => ReaderT (SeekableStream m Word8) m a) -> ReaderT (SeekableStream m Word8) m d
- readOneLayer :: forall ctx m d. (Monad m, HasField ctx RWCtx, Data ctx d) => PolyTraversal ctx m d
- type PolyTraversalW ctx m d = Proxy ctx -> (forall a. Data ctx a => a -> ReaderT (SeekableWriter m Word8) m Word32) -> d -> ReaderT (SeekableWriter m Word8) m Word32
- writeOneLayer :: forall ctx m d. (Monad m, HasField ctx RWCtx, Data ctx d) => PolyTraversalW ctx m d
- seekToField :: forall m. Monad m => Int -> ReaderT (SeekableStream m Word8) m ()
Documentation
module Data.Columbia.SeekableStream
module Data.Columbia.SeekableWriter
module Data.Columbia.SeekableStream
module Data.Columbia.SeekableWriter
class Typeable t => RW t where Source #
The RW
class describes operations that can locate entities in a stream by seeking,
and also read and write primitive types.
readData :: Monad m => ReaderT (SeekableStream m Word8) m t Source #
writeData :: Monad m => t -> ReaderT (SeekableWriter m Word8) m () Source #
Strategy/traversal combinators
(#.) :: Data ctx t => PolyTraversal ctx m t -> (forall t2. Data ctx t2 => PolyTraversal ctx m t2) -> PolyTraversal ctx m t infixl 9 Source #
(##.) :: Data ctx t => PolyTraversalW ctx m t -> (forall t2. Data ctx t2 => PolyTraversalW ctx m t2) -> PolyTraversalW ctx m t infixl 9 Source #
fixT :: Data ctx t => Proxy ctx -> (forall t2. Data ctx t2 => PolyTraversal ctx m t2) -> ReaderT (SeekableStream m Word8) m t Source #
fixTW :: Data ctx t => Proxy ctx -> (forall t2. Data ctx t2 => PolyTraversalW ctx m t2) -> t -> ReaderT (SeekableWriter m Word8) m Word32 Source #
typeCoerce :: (Typeable t, Data ctx t2) => PolyTraversal ctx m t -> (forall t3. Data ctx t3 => PolyTraversal ctx m t3) -> PolyTraversal ctx m t2 Source #
Try to cast from the first traversal; if that fails, use the second traversal.
Compound data read/write strategies
class Typeable t => RW t where Source #
The RW
class describes operations that can locate entities in a stream by seeking,
and also read and write primitive types.
readData :: Monad m => ReaderT (SeekableStream m Word8) m t Source #
writeData :: Monad m => t -> ReaderT (SeekableWriter m Word8) m () Source #
type PolyTraversal ctx m d = Proxy ctx -> (forall a. Data ctx a => ReaderT (SeekableStream m Word8) m a) -> ReaderT (SeekableStream m Word8) m d Source #
A PolyTraversal
is a reader method over a data type, parameterized over a method to read components.
Think: the targets have wide appeal, making it easy to find a buyer.
readOneLayer :: forall ctx m d. (Monad m, HasField ctx RWCtx, Data ctx d) => PolyTraversal ctx m d Source #
Function returns something PolyTraversal
. We can use this to examine the top layer
of a data structure, then seek to and read some of its components.
type PolyTraversalW ctx m d = Proxy ctx -> (forall a. Data ctx a => a -> ReaderT (SeekableWriter m Word8) m Word32) -> d -> ReaderT (SeekableWriter m Word8) m Word32 Source #
writeOneLayer :: forall ctx m d. (Monad m, HasField ctx RWCtx, Data ctx d) => PolyTraversalW ctx m d Source #
Writes the top layer of a data structure, and sells each of the sub-targets in turn.
seekToField :: forall m. Monad m => Int -> ReaderT (SeekableStream m Word8) m () Source #