Extract Value From Script (Daml Syntax)

Hi, Daml community!

I’m trying to write a helper function with a notation:

extractFirstCidFromQueryResults: (Template t) => Script([(ContractId t, t)]) -> ContractId t

Usually, in the script context, I do it like this:

 firstCidFromQuery <- fst . head <$> query @Template party

Now I want to write a helper function to hide this part:
fst . head <$>

And I can’t figure out how to do this… How can I do <$> as a first action in the function… I tried >>=, but it looks like I’m missing a concept here. Help!

Thanks!

PS

And I tried to query inside a function:

queryAndTakeFirstCid: (Template temp) => Party -> temp -> Script(ContractId temp)
queryAndTakeFirstCid party temp = query @temp party >>= \case
                                      -- ^Not in scope: type variable ‘temp’
  x:xs -> return $ fst x
  _ -> error "no cids" 

queryAndTakeFirstCid party MyTemplate

I will highly appreciate it if you can give me a clue on how to construct a function like this.

Hi @VictorShneer,

In the expression you would write within a script

firstCidFromQuery <- fst . head <$> query @Template party

you are using the <- operator to extract a value of type x from a Script x.

Hence, the expression to the right of <- must be wrapped in a Script. If you want to abstract this logic behind a helper function, the helper function should then return a Script (ContractId t) rather than just a ContractId t.

extractFirstCidFromQueryResults: (Template t) => Script([(ContractId t, t)]) -> Script (ContractId t)

Additionally, I think the Template t type-class constraint is unnecessary.

On your second point, you don’t really need the @temp type specification (it is automatically inferred by the compiler) and can write

queryAndTakeFirstCid: (Template t) => Party -> Script (ContractId t)
queryAndTakeFirstCid party = query party >>= \case
  x :: xs -> pure $ fst x
  [] -> error "no cids"

Please, note that I used :: to pattern-match a non-empty list rather than :.

Matteo

1 Like