Update type problem

Hi! I want to iterate through a list with the following checkBid function:

And get the following error:

Why is it necessary that the return type will be an Update?
And how could I solve this?

2 Likes

Hi @wolfi88, welcome to the forums!

You’re using the applicative map mapA instead of a plain map. If your rawBids are in fact just records, you can simply use map over them. You then need to use a normal let bools = ... assignment, instead of a bools <- binding.

The applicative map mapA you only need if, for example, your rawBids were instead contract ids, and you need to fetch each contract first in the checkBid function. fetch is a ledger action, so now your function has to return an Update Bool, start with a do block, and return its value via pure .... You would then bind the results of the mapA as you’ve done above.

So concretely, your current code should look like this:

let bools = map (\bid -> checkBid complainRawBid bid) rawBids

The version where you’re dealing with contract ids instead would look like this:

checkBid: ContractId RawBid -> ContractId RawBid -> Update Bool
checkBid crbCid rbCid = do
  crb <- fetch crbCid
  rb <- fetch rbCid
  let
    returnValue =
      if (rb.allocation.quantity > 0.0 then
        if ((crb.allocation.unitPrice > rb.allocation.unitPrice) && (crb.allocation.quantity <= rb.allocation.quantity)) then
          True
        else
          False
      else
        False
  pure returnValue

...

bools <- mapA (\bidCid -> checkBid complainRawBidCid bidCid) rawBidCids

Hope this helps.

3 Likes

Hi @georg!

I think I should understand better the differencies between applicative and plain map, between assignment and binding and so on, but your answer was very useful. My code works perfectly. Thank you so much!

2 Likes

A typical example for when you need mapA is the case where you want to exercise a choice over many contract ids in a list. Consider a simple choice Accept that returns a result of type Bool:

result <- exercise myCid Accept

As exercise is a ledger action (ie. changing the state of the ledger), you need to bind the right-hand side, which is of type Update Bool to a variable in order to “get access” to the wrapped Bool.

Now consider you have a list of myCids and you want to exercise the Accept choice on all of them. If you were to use a simple map with a let result = .. assignment, as in:

let results = map (\myCid -> exercise myCid Accept) myCids

what you’re getting in results will be a list of Update Bool, so [Update Bool]. But what you usually want is a list of all these “wrapped” Bools. This is what mapA allows you to do: if you use it instead, the right-hand side will be of type Update [Bool], which you can then unwrap as usual using the bind operator <-. So:

results <- mapA (\myCid -> exercise myCid Accept) myCids

will give you the expected list of bools ([Bool]) in your results variable.

Hope this helps to clarify the difference.

2 Likes