-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tools for extending Huddle specifications
We add some tools to allow extending Huddle specifications using the semigroup instance established: - We allow one to reference a HuddleItem (which is a rule, a group, or a generic def) as a Type0. - We then allow one to reference (by name) a HuddleItem from an existing spec. These two combined allow us to (somewhat) "extend" a specification in a nice manner - we can reference items from the previous spec by their name, and then selectively override things using the semigroup instance (but respecting the original ordering). There are two "disappointments" involved in this, however: - Since the items from a previous spec are referenced by name, we lose the type-safety provided by the Haskell compiler. It's quite possible to refer to an item that doesn't exist, and you won't find out until runtime. - The whole thing falls apart for generic rules. When calling a generic rule in the usual way, we do two things: - Apply the actual argument and turn it into a 'GRuleCall' which we return to the call site. - Discard the argument, create an appropriate number of fresh names and insert this into Huddle as a 'GRuleDef'. This crucially ignores any actual arguments, which is why we can pass an error as a fake argument in the Includable instance for HuddleM and have it all work. Unfortunately, what we cannot do is go from the 'GRuleDef' and extract from it the fact that, on the Haskell side, this is a function (with an unknown number of parameters). Which is very annoying. I have some ideas about resolving this second issue in a slightly-less-horrible way; they will follow in a subsequent commit.
- Loading branch information
Showing
4 changed files
with
89 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,52 @@ | ||
{-# LANGUAGE OverloadedLists #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE RecursiveDo #-} | ||
module Monad where | ||
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} | ||
{-# HLINT ignore "Use camelCase" #-} | ||
|
||
module Monad where | ||
|
||
import Codec.CBOR.Cuddle.Huddle qualified as Huddle | ||
import Codec.CBOR.Cuddle.Huddle.HuddleM | ||
import Data.Word (Word64) | ||
|
||
hdl_set :: (IsType0 t0) => t0 -> GRuleCall | ||
hdl_set = Huddle.binding $ \x -> "set" Huddle.=:= arr [0 <+ a x] | ||
|
||
spec :: Huddle | ||
spec = huddleDef $ mdo | ||
transaction <- "transaction" =:= mp | ||
[ idx 0 ==> set txIn, | ||
idx 1 ==> set txOut | ||
] | ||
txIn <- "txIn" =:= arr [ "transaction_id" ==> hash32, "index" ==> txId] | ||
txOut <- "txOut" =:= arr [ idx 0 ==> address, idx 1 ==> value] | ||
spec = huddleDef $ mdo | ||
transaction <- | ||
"transaction" | ||
=:= mp | ||
[ idx 0 ==> set txIn, | ||
idx 1 ==> set txOut | ||
] | ||
txIn <- "txIn" =:= arr ["transaction_id" ==> hash32, "index" ==> txId] | ||
txOut <- "txOut" =:= arr [idx 0 ==> address, idx 1 ==> value] | ||
txId <- "txId" =:= VUInt `sized` (2 :: Word64) | ||
address <- "address" =:= VBytes `sized` (32 :: Word64) | ||
hash32 <- "hash32" =:= VBytes `sized` (32 :: Word64) | ||
value <- "value" =:= VUInt | ||
set <- binding $ \x -> "set" =::= arr [0 <+ a x] | ||
value <- "value" =:= VUInt | ||
set <- include hdl_set | ||
|
||
setRootRules [transaction] | ||
pure () | ||
|
||
spec2 :: Huddle | ||
spec2 = | ||
spec | ||
<> huddleDef | ||
( mdo | ||
set <- include hdl_set | ||
txIn <- unsafeIncludeFromHuddle spec "txIn" | ||
txOut <- unsafeIncludeFromHuddle spec "txOut" | ||
_transaction <- | ||
"transaction" | ||
=:= mp | ||
[ idx 0 ==> set txIn, | ||
idx 1 ==> set txOut, | ||
idx 2 ==> metadata | ||
] | ||
metadata <- "metadata" =:= VBytes | ||
_value <- "value" =:= mp ["token" ==> VText, "quantity" ==> VUInt] | ||
pure () | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters