The problem here is assert
has an impure effect, so can't be used in a pure
function like mergeIou
. The easiest way to solve this is to change
mergeIou to have type Iou -> Iou -> Update Iou
and put the function in a
do-block.
ie.
mergeIou : Iou -> Iou -> Update Iou
mergeIou a b = do
assert $ a.issuer == b.issuer
assert $ a.owner == b.owner
assert $ a.currency == b.currency
pure $ a with amount = a.amount + b.amount
If you need the function to be pure, you can't use assert
. The simplest
alternative is to use Optional
to make the failure explicit in the type:
mergeIou : Iou -> Iou -> Optional Iou
mergeIou a b = do
unless (a.issuer == b.issuer) None
unless (a.owner == b.owner) None
unless (a.currency == b.currency) None
pure $ a with amount = a.amount + b.amount
To aid with debugging I suggest you use Either
instead, so you can
identify which of the assertions failed:
mergeIou : Iou -> Iou -> Either Text Iou
mergeIou a b = do
unless (a.issuer == b.issuer) $ Left "IOU issuers did not match"
unless (a.owner == b.owner) $ Left "IOU owners did not match"
unless (a.currency == b.currency) $ Left "IOU currencies did not match"
pure $ a with amount = a.amount + b.amount
For a fuller discussion of exactly what is going on here, I suggest you
read my extended answer to Trouble using the getTime
function
where I discuss the concepts of purity and encapsulating ledger
interactions in DAML.