... | ... | @@ -67,14 +67,13 @@ Let's think operationally for a moment: |
|
|
- GHC collects all the `StaticPtr` values in a table, the **static pointer table** or **SPT**. Each row contains
|
|
|
|
|
|
- The `StaticName` of the value
|
|
|
- A pointer to closure for the value itself
|
|
|
- A pointer to its `TypeRep`
|
|
|
- A `Dynamic` for its value (i.e. a pair of the value itself and its `TypeRep`)
|
|
|
|
|
|
- `decodeStatic` now proceeds like this:
|
|
|
|
|
|
- Parse a `StaticName` from the `ByteString` (failure =\> `Nothing`)
|
|
|
- Look it up in table (not found =\> `Nothing`)
|
|
|
- Compare the `TypeRep` passed to `decodeStatic` (via the `Typeable a` dictionary) with the one ine the table (not equal =\> `Nothing`)
|
|
|
- Use `fromDynamic` to compare the `TypeRep` passed to `decodeStatic` (via the `Typeable a` dictionary) with the one in the table (not equal =\> `Nothing`)
|
|
|
- Return the value
|
|
|
|
|
|
**Side note.** Another possibility is for `decodeStatic` not to take a `Typeable a` context but instead for `unStatic` to do so:: `unStatic :: Typeable a => StaticPtr a -> Maybe a`. But that seems a mess. Apart from anything else, it would mean that a value of type `StaticPtr a` might or might not point to a value of type `a`, so there's no point in having the type parameter in the first place. **End of side note.**
|
... | ... | @@ -146,7 +145,7 @@ both pieces: |
|
|
|
|
|
```wiki
|
|
|
data DynStaticPtr where
|
|
|
DSP :: Typeable a => StaticPtr a -> DynStaticPtr
|
|
|
DSP :: TypeRepT a -> StaticPtr a -> DynStaticPtr
|
|
|
|
|
|
decodeStatic :: ByteString -> Maybe (DynStaticPtr, ByteString)
|
|
|
```
|
... | ... | @@ -172,14 +171,18 @@ Now we can write `decodeSA` (the monad is just the `Maybe` monad, nothing fancy) |
|
|
```wiki
|
|
|
decodeSA :: forall b. Typeable b => ByteString -> Maybe (StaticApp b, ByteString)
|
|
|
decodeSA bs
|
|
|
= do { (DSP (fun :: StaticPtr tfun), bs1) <- decodeStatic bs
|
|
|
; (DSP (arg :: StaticPtr targ), bs2) <- decodeStatic bs1
|
|
|
= do { (DSP (trf :: TypeRepT tfun) (fun :: StaticPtr tfun), bs1) <- decodeStatic bs
|
|
|
; (DSP (tra :: TypeRepT targ) (arg :: StaticPtr targ), bs2) <- decodeStatic bs1
|
|
|
-- At this point we have
|
|
|
-- Typeable b (from caller)
|
|
|
-- Typeable tfun (from first DSP)
|
|
|
-- Typeable targ (from second DSP)
|
|
|
; fun' :: StaticPtr (targ->b) <- cast fun
|
|
|
; Refl <- eqTT ....
|
|
|
|
|
|
; fun' :: StaticPtr (targ->b) <- cast ( :: tfun :~: targ -> b) fun
|
|
|
; return (SA fun' arg, bs2) }
|
|
|
|
|
|
cast :: (a :~: b) -> a -> Maybe b
|
|
|
```
|
|
|
|
|
|
|
... | ... | |