Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
-
class
(
forall
a.
Show
(
NestedCtxt_
blk f a),
SameDepIndex
(
NestedCtxt_
blk f)) =>
HasNestedContent
f blk
where
- unnest :: f blk -> DepPair ( NestedCtxt f blk)
- nest :: DepPair ( NestedCtxt f blk) -> f blk
- data family NestedCtxt_ blk :: ( Type -> Type ) -> Type -> Type
- curriedNest :: HasNestedContent f blk => NestedCtxt f blk a -> a -> f blk
-
newtype
NestedCtxt
f blk a =
NestedCtxt
{
- flipNestedCtxt :: NestedCtxt_ blk f a
- castNestedCtxt :: ( NestedCtxt_ blk f a -> NestedCtxt_ blk' f a) -> NestedCtxt f blk a -> NestedCtxt f blk' a
- mapNestedCtxt :: ( NestedCtxt_ blk f a -> NestedCtxt_ blk' f' a') -> NestedCtxt f blk a -> NestedCtxt f' blk' a'
- castSomeNestedCtxt :: ( forall a. NestedCtxt_ blk f a -> NestedCtxt_ blk' f a) -> SomeSecond ( NestedCtxt f) blk -> SomeSecond ( NestedCtxt f) blk'
- mapSomeNestedCtxt :: ( forall a. NestedCtxt_ blk f a -> NestedCtxt_ blk' f' a) -> SomeSecond ( NestedCtxt f) blk -> SomeSecond ( NestedCtxt f') blk'
- module Ouroboros.Consensus.Util.DepPair
-
data
SomeSecond
(f ::
Type
->
Type
->
Type
) a
where
- SomeSecond :: !(f a b) -> SomeSecond f a
Block contents
class ( forall a. Show ( NestedCtxt_ blk f a), SameDepIndex ( NestedCtxt_ blk f)) => HasNestedContent f blk where Source #
Nested content inside a block
Consider a simplified version of the hard fork combinator, defining
type HardFork a b = Either a b
Then encoding
Hardfork ByronBlock ShelleyBlock
is easy, in the same way
that we encode
any
Either
. The
header
of such a block will have type
HardFork (Header ByronBlock) (Header ShelleyBlock)
and encoding those (for example, to send them across the network) is
similarly trivial. But now suppose we want to read a header from disk. We do
not store headers directly, but instead store the blocks. The DB will know
the offset and length (both in bytes) of the header inside the block, but
how do we decode such a header? If it's a Byron block, we should use the
decoder for
Header ByronBlock
, and similarly for Shelley, but how should
we express this more generally?
Here is where
HasNestedContent
comes in. Continuing the example, we can
unnest
a
Header (HardFork ByronBlock ShelleyBlock)
into a pair of values,
where the first value (a
NestedCtxt
) tells us what type of block we have,
and the second value gives us the actual header. So, if the first value says
"this is a Byron block", the second value is a
Header ByronBlock
, and vice
versa. In other words, this is a dependent pair.
This then solves the serialisation problem: we expect a
dependent
decoder
which,
given
a
NestedCtxt
identifying the block type, decodes the raw
bytes from the block into the type indicated by that
NestedCtxt
.
TODO: We could perhaps define this independent of blocks in
DepPair
.
Nothing
unnest :: f blk -> DepPair ( NestedCtxt f blk) Source #
default unnest :: ( TrivialDependency ( NestedCtxt f blk), TrivialIndex ( NestedCtxt f blk) ~ f blk) => f blk -> DepPair ( NestedCtxt f blk) Source #
nest :: DepPair ( NestedCtxt f blk) -> f blk Source #
default nest :: ( TrivialDependency ( NestedCtxt f blk), TrivialIndex ( NestedCtxt f blk) ~ f blk) => DepPair ( NestedCtxt f blk) -> f blk Source #
Instances
CanHardFork xs => HasNestedContent Header ( HardForkBlock xs) Source # | |
Defined in Ouroboros.Consensus.HardFork.Combinator.Block unnest :: Header ( HardForkBlock xs) -> DepPair ( NestedCtxt Header ( HardForkBlock xs)) Source # nest :: DepPair ( NestedCtxt Header ( HardForkBlock xs)) -> Header ( HardForkBlock xs) Source # |
|
HasNestedContent Header m => HasNestedContent Header ( DualBlock m a) Source # | |
data family NestedCtxt_ blk :: ( Type -> Type ) -> Type -> Type Source #
Context identifying what kind of block we have
In almost all places we will use
NestedCtxt
rather than
NestedCtxt_
.
Instances
curriedNest :: HasNestedContent f blk => NestedCtxt f blk a -> a -> f blk Source #
Flip type arguments
newtype NestedCtxt f blk a Source #
Version of
NestedCtxt_
with the type arguments swapped
NestedCtxt
must be indexed on
blk
: it is the block that determines this
type. However, we often want to partially apply the second argument (the
functor), leaving the block type not yet defined.
NestedCtxt | |
|
Instances
castNestedCtxt :: ( NestedCtxt_ blk f a -> NestedCtxt_ blk' f a) -> NestedCtxt f blk a -> NestedCtxt f blk' a Source #
mapNestedCtxt :: ( NestedCtxt_ blk f a -> NestedCtxt_ blk' f' a') -> NestedCtxt f blk a -> NestedCtxt f' blk' a' Source #
Existentials
castSomeNestedCtxt :: ( forall a. NestedCtxt_ blk f a -> NestedCtxt_ blk' f a) -> SomeSecond ( NestedCtxt f) blk -> SomeSecond ( NestedCtxt f) blk' Source #
mapSomeNestedCtxt :: ( forall a. NestedCtxt_ blk f a -> NestedCtxt_ blk' f' a) -> SomeSecond ( NestedCtxt f) blk -> SomeSecond ( NestedCtxt f') blk' Source #
Convenience re-exports
data SomeSecond (f :: Type -> Type -> Type ) a where Source #
Hide the second type argument of some functor
SomeSecond f a
is isomorphic to
Some (f a)
, but is more convenient in
partial applications.
SomeSecond :: !(f a b) -> SomeSecond f a |