Custom function on Trigger

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 :slight_smile:

1 Like