However I’ll give here a try to explain a possible solution too.
So most important, DAML is based on Haskell. A mostly pure functional programming language. This means in practice that there don’t exist
variables. There are only
bindings. They are not mutable, otherwise they would have been called
variables (you see the slight difference in naming here? It’s important to distinguish). However you can re-define a binding like this:
let foo = "hamspam"
let foo = "spam"
This may look like mutating foo but it’s really is just defining foo again with a different bound value.
So if you do something like this here:
let c = 2
let add a b = do
let c = a
b + c
add 2 3
c which has been defined before the function
add won’t magically be bound to a new value everytime you call add.
Now back to your code.
So I get the idea that you try to conditionally want to bind a value to data1 & data2 depending on what is in the parties list. However your current code (assuming one could mutate) has some flaws. Your call in the end with
create ContractB with data1, data2 could result in usage of variables which have an empty string as a value, simply because it’s not guranteed that the value’s you’re effectively matching for aren’t in the list. However if this is your intention and assuming that you want that the last matching element in the list is used for data1 & the last non matching element is used for data2 then the adapted code probably looks like this:
data Either a b = Left a | Right b
controller CollabResult : ContractId MasterData
parties : [Party]
results <- forA parties \party -> do
(_, someData) <- lookupByKey @ContractAs (party, keyData)
if someData.party == party then Left someData.data1
else Right someData.data2
let reversedResults = reverse results
let optData1 = findOptional (\it ->
case it of
Left data1 -> Some data1
Right _ -> None) reversedResults
let optData2 = findOptional (\it ->
case it of
Left _-> None
Right data2 -> Some data2) reversedResults
let data1 = fromOptional "" optData1
let data2 = fromOptional "" optData2
create ContractB with data1, data2
Important to note here is that in comparison to your code, I respected the properties of how
forA actually works.
forA is a function which returns not
void (in daml called
unit) but something of
Update [A], which means a list of
A's wrapped in an
Update. To actually be able to do anything with this return type, you need to be within a contract declaration (which we currently are) and use
YOURFANCYNAME <- such that the operation
bind is executed on this value with it’s result being bound to
The type of
YOURFANCYNAME will then be of
[A], so the unwrapped list which you now can operate on.
Besides, the code itself now maps your list of parties to a list of Either’s.
Now we want from that result the last left and last right as these are equivalent to the values which would have been assigned to data1 & data2 in your pseudo code. For searching these in the list we use
findOptional, which returns the first matching entry going from the beginning to the end. Now, because we want to find the first matching entry from the end to the beginning, we need to reverse the list first, then we can do the search.
However, because it’s possible that the list never contains either an left xor right, the result of
findOptional will always be something of
Optional A (which means, there might be a value of A or not). To not fail here and continue, we can make use of the
fromOptional function which takes first a default value and then the optional which should be checked for it’s value. If it does contain a value, this value is returned, if not your provided default value (in this case an empty string) is returned.
Now you’ve extracted data1 & data2 to use it for your call to
create (which btw also returns something of
Update A, however because it is the last statement in the do block it is fine to return as do blocks in contract definitions expect something of type
Update A to be returned).
Finally, this logic seems to be a bit akward to me. I don’t recommend this code without knowing what exactly your intentions are here. I’m pretty sure that there is a different way to solve your idea