Daml Syntax Help
I have the trigger code below, and I’m wondering if I can write a do block inside a filter’s callback function. I’ve written in a comment in the code “NEED HELP HERE”
when trying to build, I get daml/AcceptSwapTrigger.daml:36:13: error: parse error (possibly incorrect indentation or mismatched brackets)
But my IDE is acting strange and it’s not giving me any red error squiggles. And I’m not sure what might be causing my IDE to do that. I’ve tried to launch Daml studio, and followed the steps for installing it in PATH, etc, but that wasn’t working either.
acceptSwapTrigger: T.Trigger ()
acceptSwapTrigger = T.Trigger
{ initialize = pure (),
updateState = \_ -> pure (),
registeredTemplates = T.RegisteredTemplates [T.registeredTemplate @Asset, T.registeredTemplate @Trade, T.registeredTemplate @AssetHoldingAccount, T.registeredTemplate @TransferPreApproval],
rule = \p -> do
tradeRequests <- T.query @Trade
allAssetContracts <- T.query @Asset
let isMyIncomingTrades = (\tradeRequests -> tradeRequests.receiver == p)
let myTrades = filter (\(_, contract) -> isMyIncomingTrades contract) tradeRequests
debug ("asset holding account invites", myTrades)
unless ( DA.Foldable.null myTrades ) do
case myTrades of
[] -> pure ()
(tradeCid, c) :: _ -> do
let isRequestedAsset = (\asset -> do
-- NEED HELP HERE, isRequestedAsset is a filter function.
-- Can I use "do" here? I want to compare a fetched contract's attribute
requestedAssetTxPreApproval <- T.queryContractId p c.requestedAssetsTxPreApprovalCid
asset.assetType == requestedAssetTxPreApproval.asset.assetType && asset.owner == p)
let requestedAssets = filter(\(cid,contract) -> isRequestedAsset contract) allAssetContracts
debug("REQUESTED ASSETS", requestedAssets)
let requestedAssetCids = map fst requestedAssets
T.dedupExercise tradeCid Trade_Settle with
requestedAssetCids = requestedAssetCids
debug $ "TRIGGERED",
heartbeat = None
}
You need to indent the body of the let binding further than the let itself so
let isRequestedAsset = (\asset -> do
-- NEED HELP HERE, isRequestedAsset is a filter function.
-- Can I use "do" here? I want to compare a fetched contract's attribute
requestedAssetTxPreApproval <- T.queryContractId p c.requestedAssetsTxPreApprovalCid
asset.assetType == requestedAssetTxPreApproval.asset.assetType && asset.owner == p)
Your next issue is that queryContractId does not take a party argument for triggers so drop that:
requestedAssetTxPreApproval <- T.queryContractId c.requestedAssetsTxPreApprovalCid
Next, your filter function needs to work in TriggerA so you need to use filterA and pure in the filter function.
Finally, queryContractId returns an Optional so you need to handle the case where it’s not present. Putting the last two fixes together you get
let isRequestedAsset = (\asset -> do
-- NEED HELP HERE, isRequestedAsset is a filter function.
-- Can I use "do" here? I want to compare a fetched contract's attribute
requestedAssetTxPreApproval <- T.queryContractId c.requestedAssetsTxPreApprovalCid
pure $ optional False (\preapproval -> asset.assetType == preapproval.asset.assetType && asset.owner == p) requestedAssetTxPreApproval)
requestedAssets <- filterA (\(cid,contract) -> isRequestedAsset contract) allAssetContracts
which compiles fine.
As for why vscode doesn’t show issues, take a look at View → Output → Select daml language server from the drop down and see if there’s anything in there. Also try Ctrl/Cmd-Shift-P → reload window and see if the issue disappears.