| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
Plutarch.LedgerApi.V3.Value
Description
Conversions between ledger API representations of Values and the new
PBuiltinValue, plus some utility functions.
Why is this module necessary?
In almost all situations, Values will be provided to a script as their
Data encodings, whether this is through an input or a PScriptContext.
plutarch-ledger-api has an extensive collection of functions for dealing
with such representations, as well as a range of newtype wrappers to
provide guarantees of form when doing so.
However, as these operations have to work over (effectively) nested cons
lists, they are not efficient for many operations, especially simpler ones
like lookups or primitive insertions. In this regard, PBuiltinValue excels,
as these are calls to builtin operations, which are much more efficient.
However, some conversion cost must be paid to go from the Data encoding to
a PBuiltinValue.
In addition to this, the UnValueData primitive has quite specific
expectations of any Data it is given. More precisely, the argument must:
- Be made using the
Mapconstructor; - Every 'key' must be encoded using the
Bconstructor, and be at most 32 bytes in length; - Every 'value' must be a non-empty list of key-value pairs.
- Every 'inner key' must be encoded using the
Bconstructor, and be at most 32 bytes in length; - Every 'inner value' must be encoded using the
Iconstructor, and be non-zero, as well as fitting within a 128-bit signed integer; - 'Keys', both 'outer' and 'inner', must be in strictly ascending order, which implies no duplicates.
Any deviation from this will cause the builtin to error. Thus, of all the
newtypes provided for structural safety by plutarch-ledger-api, only
PMintValue is suitable.
To make matters worse, the inverse ValueData builtin does not guarantee
that an arbitrary PBuiltinValue will satisfy the structural requirements of
a PMintValue, as it may contain an Ada entry. Thus, if 'converting back'
is required, we can only guarantee a PSortedValue. Any other conversion is
technically speaking unsafe and may error. Worse still, there is no
straightforward way to verify what kind of 'inner' or 'outer' keys a
PBuiltinValue contains without converting it first!
Thus, this module provides clearly labelled conversions, safe and unsafe, as
well as some helper wrapper functions to make PBuiltinValue easier to use
with other types provided by plutarch-ledger-api.
Since: 3.7.0
Synopsis
- pfromRawValue :: forall (r :: S -> Type) (s :: S). Term s PRawValue -> Term s r -> Term s (PBuiltinValue :--> r) -> Term s r
- pfromSortedValue :: forall (r :: S -> Type) (s :: S). Term s PSortedValue -> Term s r -> Term s (PBuiltinValue :--> r) -> Term s r
- pfromMintValue :: forall (s :: S). Term s (PAsData PMintValue) -> Term s PBuiltinValue
- ptoSortedValue :: forall (s :: S). Term s PBuiltinValue -> Term s (PAsData PSortedValue)
- ptoLedgerValue :: forall (r :: S -> Type) (s :: S). Term s PBuiltinValue -> Term s r -> Term s (PAsData PLedgerValue :--> r) -> Term s r
- ptoLedgerValue' :: forall (s :: S). Term s PBuiltinValue -> Term s PLedgerValue
- ptoMintValue :: forall (r :: S -> Type) (s :: S). Term s PBuiltinValue -> Term s r -> Term s (PAsData PMintValue :--> r) -> Term s r
- punsafeFromRawValue :: forall (s :: S). Term s (PAsData PRawValue) -> Term s PBuiltinValue
- punsafeFromSortedValue :: forall (s :: S). Term s (PAsData PSortedValue) -> Term s PBuiltinValue
- punsafeToLedgerValue :: forall (s :: S). Term s PBuiltinValue -> Term s (PAsData PLedgerValue)
- punsafeToMintValue :: forall (s :: S). Term s PBuiltinValue -> Term s (PAsData PMintValue)
- pemptyBuiltinValue :: forall (s :: S). Term s PBuiltinValue
- psingletonBuiltinValue :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PInteger :--> PBuiltinValue)))
- pvalueOf :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PBuiltinValue :--> PInteger)))
- plovelaceValueOf :: forall (s :: S). Term s (PBuiltinValue :--> PInteger)
- preplaceAmountPositive :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PPositive :--> (PBuiltinValue :--> PBuiltinValue))))
- preplaceAmountNegative :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PPositive :--> (PBuiltinValue :--> PBuiltinValue))))
- pdeleteAmount :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PBuiltinValue :--> PBuiltinValue)))
Conversions
Safe
pfromRawValue :: forall (r :: S -> Type) (s :: S). Term s PRawValue -> Term s r -> Term s (PBuiltinValue :--> r) -> Term s r Source #
After verifying the conversion is safe, convert a PRawValue Data
representation into a PBuiltinValue. To save on allocations, this is
written in a continuation-passing style:
- The second argument is what should happen if validation fails; and
- The third argument is what should happen if validation succeeds.
Important note
This operation is slow, as it has to check the entire input.
Since: 3.7.0
pfromSortedValue :: forall (r :: S -> Type) (s :: S). Term s PSortedValue -> Term s r -> Term s (PBuiltinValue :--> r) -> Term s r Source #
As pfromRawValue, except for PSortedValues instead. This is more
efficient, as we only need to check for the absence of zero amounts.
Since: 3.7.0
pfromMintValue :: forall (s :: S). Term s (PAsData PMintValue) -> Term s PBuiltinValue Source #
Convert the Data representation of a PMintValue to a PBuiltinValue.
This is done via a builtin (thus efficient), and is safe.
Since: 3.7.0
ptoSortedValue :: forall (s :: S). Term s PBuiltinValue -> Term s (PAsData PSortedValue) Source #
Convert a PBuiltinValue into the Data representation of a
PSortedValue. This is done via a builtin (thus efficient), and is safe.
If you need to convert to something less specific, use pupcast.
Since: 3.7.0
ptoLedgerValue :: forall (r :: S -> Type) (s :: S). Term s PBuiltinValue -> Term s r -> Term s (PAsData PLedgerValue :--> r) -> Term s r Source #
Checks for an Ada entry in the input PBuiltinValue. If none is found,
produce the second argument; otherwise, convert the PBuiltinValue into a
PAsData PLedgerValue and call the third argument with it.
Since: 3.7.0
ptoLedgerValue' :: forall (s :: S). Term s PBuiltinValue -> Term s PLedgerValue Source #
As ptoLedgerValue, but 'fills in' a zero ADA entry if one is missing.
This is a costly operation, as it must be done after conversion. Use with
care.
Since: 3.7.0
ptoMintValue :: forall (r :: S -> Type) (s :: S). Term s PBuiltinValue -> Term s r -> Term s (PAsData PMintValue :--> r) -> Term s r Source #
As ptoLedgerValue, except the check is for the absence of an Ada entry,
and the third argument is called with a PAsData PMintValue instead when
appropriate.
Since: 3.7.0
Unsafe
punsafeFromRawValue :: forall (s :: S). Term s (PAsData PRawValue) -> Term s PBuiltinValue Source #
Convert the Data representation of a PRawValue into a PBuiltinValue
while not doing any checks.
This is not safe, and will error if any of the invariants of
PBuiltinValue are violated. Use with care.
Since: 3.7.0
punsafeFromSortedValue :: forall (s :: S). Term s (PAsData PSortedValue) -> Term s PBuiltinValue Source #
As punsafeFromRawValue, except for PSortedValues instead. The same
caveats apply.
Since: 3.7.0
punsafeToLedgerValue :: forall (s :: S). Term s PBuiltinValue -> Term s (PAsData PLedgerValue) Source #
Convert a PBuiltinValue into a PAsData PLedgerValue without checking
anything. Only use this if you are certain that the PBuiltinValue does not
violate any internal invariants of PLedgerValue. In particular, there must
be an Ada amount in the argument PMintValue.
Since: 3.7.0
punsafeToMintValue :: forall (s :: S). Term s PBuiltinValue -> Term s (PAsData PMintValue) Source #
Convert a PBuiltinValue into a PAsData PLedgerValue without checking
anything. Only use this if you are certain that the PBuiltinValue does not
violate any internal invariants of PMintValue. In particular, there should
not be an Ada amount in the argument PMintValue.
Since: 3.7.0
Construction
pemptyBuiltinValue :: forall (s :: S). Term s PBuiltinValue Source #
The PBuiltinValue without any amounts.
Since: 3.7.0
psingletonBuiltinValue :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PInteger :--> PBuiltinValue))) Source #
A PBuiltinValue containing an amount of a single currency-token name
combination. If the PInteger argument is 0, this will be identical to
pemptyBuiltinValue.
Since: 3.7.0
Queries
pvalueOf :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PBuiltinValue :--> PInteger))) Source #
Look up the amount associated with a given combination of PCurrencySymbol
and PTokenName in the given PBuiltinValue. As PBuiltinValue cannot
store zero amounts, if this returns 0, it means that no amount is
associated with the given combination of PCurrencySymbol and PTokenName
in this 'PBuiltinValue.
Since: 3.7.0
plovelaceValueOf :: forall (s :: S). Term s (PBuiltinValue :--> PInteger) Source #
As pvalueOf, but for Lovelace specifically. The same caveats apply.
Since: 3.7.0
Updates
preplaceAmountPositive :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PPositive :--> (PBuiltinValue :--> PBuiltinValue)))) Source #
Replace the amount at the given currency-token name combination in the
given PBuiltinValue with the given amount. The new amount will be positive.
If the given currency-token name combination does not exist, create it.
Note
A PBuiltinValue cannot store an amount that would not fit into a 128-bit
signed integer. This function will error if the result would be forced to
store such an amount.
Since: 3.7.0
preplaceAmountNegative :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PPositive :--> (PBuiltinValue :--> PBuiltinValue)))) Source #
Replace the amount at the given currency-token name combination in the
given PBuiltinValue with the given amount. The new amount will be negative.
If the given currency-token name combination does not exist, create it.
Note
A PBuiltinValue cannot store an amount that would not fit into a 128-bit
signed integer. This function will error if the result would be forced to
store such an amount.
Since: 3.7.0
pdeleteAmount :: forall (s :: S). Term s (PCurrencySymbol :--> (PTokenName :--> (PBuiltinValue :--> PBuiltinValue))) Source #
Remove any amount associated with the given currency-token name combination
in the given PBuiltinValue. If there is no such combination in the given
PBuiltinValue, this does nothing.
Since: 3.7.0