@@ -519,16 +519,15 @@ scripts representing modules; the latter are subject to an additional
519
519
syntactic restriction that the script body must be a tuple. We change
520
520
the ` Script ` type accordingly
521
521
```
522
- data Script = CompleteValidatorScript CompiledCode
523
- | ValidatorScript CompiledCode [ScriptArg]
524
- | CompleteModuleScript CompiledCode
525
- | ModuleScript CompiledCode [ScriptArg]
522
+ data Script = ValidatorScript CompiledCode [ScriptArg]
523
+ | ModuleScript CompiledCode [ScriptArg]
526
524
```
527
525
so that the deserializer can easily check the new syntactic
528
526
restriction. ` Script ` s used as ` ScriptArg ` s may only be of the
529
527
` ModuleScript ` form (this requires a dynamic check). The idea is that
530
528
a module provides a number of exports, which are the components of the
531
- tuple.
529
+ tuple. (Again, special cases for an empty list of script arguments
530
+ can be included in this type if desired).
532
531
533
532
In addition, expressions ` M ` referring to modules (of the form `proj j
534
533
Mods` ) may only appear in contexts of the form ` proj i M`, projecting
@@ -636,6 +635,20 @@ these.
636
635
It is ` Module ` values that would then be serialised to produce scripts
637
636
for inclusion in transactions.
638
637
638
+ In the 'unboxed modules' variation we need to distinguish two kinds of
639
+ scripts, scripts which define modules, and scripts which define
640
+ validators. In Plinth, this distinction can be made in the types, by
641
+ turning the ` Module ` type into a GADT with an extra parameter, of type
642
+ ```
643
+ data ScriptType = ModuleScript | ValidatorScript
644
+ ```
645
+ ` applyModule ` would be given a more restrictive type:
646
+ ```
647
+ applyModule :: Module s (a->b) -> Module ModuleScript a -> Module s b
648
+ ```
649
+ thus ensuring that only scripts representing modules are passed as
650
+ script arguments.
651
+
639
652
### Plutus Ledger Language Versions
640
653
641
654
Plutus ledger language version is what "Plutus V1", "Plutus V2", "Plutus V3" refer to.
@@ -1356,6 +1369,56 @@ algorithms, because their code is smaller, and easier to fit within
1356
1369
the script size limit. Removing the need to make such choices can
1357
1370
potentially improve performance considerably.
1358
1371
1372
+ ### Example: Defining and using a Set module
1373
+
1374
+ As an example of how the module system might be used in a high-level
1375
+ language, consider the following code, which defines and uses a module
1376
+ implementing set insertion and membership testing, using an ordered
1377
+ binary tree.
1378
+ ```
1379
+ data Tree a = Leaf | Branch (Tree a) a (Tree a)
1380
+
1381
+ empTree = Leaf
1382
+
1383
+ insTree a Leaf = Branch Leaf a Leaf
1384
+ insTree a (Branch l b r)
1385
+ | a < b = Branch (insTree a l) b r
1386
+ | a > b = Branch l b (insTree a r)
1387
+ | a== b = Branch l b r
1388
+
1389
+ memTree a Leaf = False
1390
+ memTree a (Branch l b r)
1391
+ | a < b = memTree a l
1392
+ | a > b = memTree a r
1393
+ | a== b = True
1394
+
1395
+ data Set = Set {emptySet :: forall a. Tree a,
1396
+ insertSet :: forall a. Ord a => a -> Tree a -> Tree a,
1397
+ memberSet :: forall a. Ord a => a -> Tree a -> Bool}
1398
+
1399
+ setMod = Set empTree insTree memTree
1400
+
1401
+ setModule :: Module Set
1402
+ setModule = makeModule ($$(PlutusTx.compile [| setMod |]))
1403
+
1404
+ client set redeemer _ = memberSet set redeemer s
1405
+ where s = insertSet set 1 (insertSet set 2 (emptySet set))
1406
+
1407
+ clientModule = makeModule ($$(PlutusTx.compile [| client |]))
1408
+ `applyModule` setModule
1409
+ ```
1410
+ Here the module signature is represented by a Haskell record type;
1411
+ Haskell records are compiled into tuples in UPLC, and the record
1412
+ fields are all values (once fixpoints are floated upwards to the
1413
+ module level), so the ` setModule ` in this example fits the 'unboxed
1414
+ modules' syntactic restrictions. The client script takes the record as
1415
+ an argument, and uses the module exports via record field selectors,
1416
+ which compile to projections from the tuple. Thus the client also
1417
+ meets the syntactic restrictions for 'unboxed modules'. To make use
1418
+ of these modules, the off-chain code must construct a UTxO
1419
+ containing ` setModule ` as a reference script, and include it as a
1420
+ reference UTxO in transactions that use the client.
1421
+
1359
1422
### Related work
1360
1423
1361
1424
#### Merkelized Validators
0 commit comments