Skip to content
Discussions/App Development/How to execute a choice that returns Either (ContractA) (ContractB) in a scriptForum ↗

How to execute a choice that returns Either (ContractA) (ContractB) in a script

App Development5 posts385 views5 likesLast activity Jan 2021
JA
jamesljaworski85OP
Jan 2021

Hey DAMLer’s!

I am working on converting my scenario to a script. Our model is based on ex-cdm-swaps.

I am trying to execute this line in my script.

eiCid <- fromRightS "Unknown error" =<< (submit p2.p do exerciseCmd epCid EP.Accept with exerciser = p2.p)

Here is the error I am getting.

C:\Users\James Jaworski\OneDrive\BloqbookV2\sandbox-srm\src\daml\DA\srm\Test\Event.daml:102:12: error:
    • Couldn't match type ‘Scenario’ with ‘Script’
      Expected type: Script (ContractId EventInstance)
        Actual type: Scenario (ContractId EventInstance)
    • In a stmt of a 'do' block:
        eiCid <- fromRightS "Unknown error"
                   =<<
                     (submit
                        (DA.Internal.Record.getField @"p" p2)
                        do exerciseCmd
                             epCid
                             EP.Accept {exerciser = (DA.Internal.Record.getField @"p" p2)})
      In the expression:
        do debug "Starting market setup..."
           let p1 = ...
           let p2 = ...
           let p3 = ...
           ....
      In an equation for ‘setupMarketWithParties’:
          setupMarketWithParties parties@CdmParties {..}
            = do debug "Starting market setup..."
                 let p1 = ...
                 let p2 = ...
                 ....typecheck
C:\Users\James Jaworski\OneDrive\BloqbookV2\sandbox-srm\src\daml\DA\srm\Test\Event.daml:102:54: error:
    • Couldn't match type ‘Script’ with ‘Scenario’
        arising from a functional dependency between:
          constraint ‘HasSubmit Scenario Commands’
            arising from a use of ‘submit’
          instance ‘HasSubmit Script Commands’ at <no location info>
    • In the second argument of ‘(=<<)’, namely
        ‘(submit
            (DA.Internal.Record.getField @"p" p2)
            do exerciseCmd
                 epCid
                 EP.Accept {exerciser = (DA.Internal.Record.getField @"p" p2)})’
      In a stmt of a 'do' block:
        eiCid <- fromRightS "Unknown error"
                   =<<
                     (submit
                        (DA.Internal.Record.getField @"p" p2)
                        do exerciseCmd
                             epCid
                             EP.Accept {exerciser = (DA.Internal.Record.getField @"p" p2)})
      In the expression:
        do debug "Starting market setup..."
           let p1 = ...
           let p2 = ...
           let p3 = ...
           ....typecheck
Peek Problem (Alt+F8)
No quick fixes available

When I start to check this out, I think that it has something to do with the Accept choice of the EventProposal contract returning Either (ContractId EventProposal) (ContractId EventInstance).

In this case, I am looking to return the right side, EventInstance.

From the docs, it looks like step 5 is what I am trying to figure out. If so, what is the best way to specify which return the compiler in the script should expect?

CO
cocreature
Jan 2021

Looking at the error, it seems like fromRightS is the culprit here and has a type similar to Either a b -> Scenario b. Could you share the definition of fromRightS with us?

JA
jamesljaworski85
Jan 2021
cocreature:

fromRightS

You’re correct. It comes from here. As I have learned from this exercise, you can’t return the results of a scenario within a script.

After seeing that, I thought maybe I could do something like this but it threw an error. I assume it’s looking for one output.

( _ , eiCid) <- submit p2.p do exerciseCmd epCid EP.Accept with exerciser = p2.p

So perhaps, I could convert this to a script?

CO
cocreature
Jan 2021

You can either use pattern matching (regardless of whether you use scenarios or scripts as follows):

Right eiCid <- submit p2.p do exerciseCmd epCid EP.Accept with exerciser = p2.p

That will crash if you get a Left but contrary to fromRightS it won’t include a (potentially) useful error message so I’d recommend against this outside of test code.

The other option is to make fromRightS work with Script. In this case, this is luckily a pretty small change. abort has the type CanAbort m => Text -> m a. Both Script and Scenario are an instance of CanAbort (Update is as well). So we don’t have to change the definition at all, all we have to do is to generalize the type and it works for both Scenario and Script. Of course, if you only need it for Script, you can also just replace the Scenario in the type by Script:

fromRightS : CanAbort m => Text -> Either a b -> m b
fromRightS msg (Left _) = abort msg
fromRightS _ (Right x) = return x
JA
jamesljaworski85
Jan 2021

Interesting. Thanks for the help on this.

There are quite a bit of helper functions in the test folder to help make the former scenarios more legible. I have been trying to minimize how many of them I try to change or update, as they’re not critical for us at this stage.

For right now, I just want to update so that we can initialize the ledger and display one workflow using React ui on DABL for demo purposes.

Thanks again for your help working through these and teaching me some new DAML tricks along the way!

← Back to Discussions