Hi,
I am still learning DAML. I have this trigger and I want to implement a custom function which I will call inside the rule of the Trigger I defined.
But I get this error
Here is my code :
processTrade : (ContractId OB.OrderBook,OB.OrderBook) -> (ContractId OB.OrderBook,OB.OrderBook) -> Decimal -> Decimal -> ()
processTrade (sellCid,currentSell) (bCid,currentBuy) bidPrice askPrice = do
let buyTotalAmount = (askPrice * intToDecimal(currentBuy.qty)) * (1.01)
buyTransactionFee = (askPrice * intToDecimal(currentBuy.qty)) * (0.01)
sellTotalAmount = (bidPrice * intToDecimal(currentSell.qty)) * (1.01)
sellTransactionFee = (bidPrice * intToDecimal(currentSell.qty)) * (0.01)
debugRaw $ "MATCHING : " <> show (currentSell.qty) <> "=" <> show (currentBuy.qty)
when(currentSell.qty <= currentBuy.qty) $ do
T.dedupExercise bCid OB.ProcessTrade with ..
I get error on return type, Im still struggling to undertand some return type mismatch.
Thanks for the help, let me know whats the best way to implement this.
Best,
Hi @ariscatan,
In Daml, a do
block returns the value of its last expression. The signature of your function says it returns ()
, but the code of the function has
when(currentSell.qty <= currentBuy.qty) $ do
T.dedupExercise bCid OB.ProcessTrade with ..
as its last expression, so the return type will be that of when
. Looking at its documentation, you can see that it’s returning f ()
, which isn’t all that helpful if we don’t know what f
is. But the signature tells us it has to be the same f
as the second argument, namely
do T.dedupExercise bCid OB.ProcessTrade with ..
If you look at the documentation for dedupExercise
, you’ll see that its return type is TriggerA s ()
, meaning that in this case f
is TriggerA s
. In this type signature, s
is not bound to anything, so you can leave it unbound too; this means that the return value of when
in this particular case is
TriggerA s ()
and thus the signature of your function should be
processTrade : (ContractId OB.OrderBook,OB.OrderBook) -> (ContractId OB.OrderBook,OB.OrderBook) -> Decimal -> Decimal -> TriggerA s ()
1 Like
One quick fix that works for most functions: if you delete the type annotation, i.e. the line starting with processTrade :
, and your module has no errors in it, the inferred type signature will appear as a link above your function definition. You can click on it to insert it automatically.
Some functions cannot be inferred without a type signature, so this doesn’t always work, but it works most of the time.
1 Like
Awesome! this solve my problem. Thanks
1 Like
Hi,
I have another concern. I want to pass the current party that runs the trigger to my custom function. I tried this but it gives me an error. I made another trigger function in my Trigger file and call it, but Id like to pass also the party that runs the ledger so that I can perform exerciseByKey on my function.
updateBidAndAskPrice : Party -> T.TriggerA s ()
updateBidAndAskPrice p = do
-- do exerciseByKey
But when I build I get these errors
daml/Triggers/AutoAcceptTrade3.daml:96:13: error:
• Couldn't match expected type ‘T.TriggerA () ()’
with actual type ‘Party -> T.TriggerA s4 ()’
• Probable cause: ‘updateBidAndAskPrice’ is applied to too few arguments
In a stmt of a 'do' block: updateBidAndAskPrice
In the second argument of ‘($)’, namely
‘do debugRaw $ "LB -> LS"
let (sCid, currentSell) = List.head limit_orders_sell
let limit_orders_buy_sorted = sortOrderBookByQty limit_orders_buy
let (bCid, currentBuy) = List.head limit_orders_buy_sorted
Let me know if this is possible. Thanks
From the error it looks like you are not passing the party to updateBidAndPrice
. You need to call it with something like updateBidAndPrice yourpartyhere
. If you show the code that calls it, we might be able to provide a more concrete suggestion.
Thanks @cocreature I learned how to make it work
1 Like