Optional Int to Int ? (Casting: is it possible?)

Is there a way to turn an Optional Int type to an Int type in Daml?

if (winningParticipant == betPayload.participantToWin)
          then do  
            let
              -- the below creates the following: (["Giants", "Jets"], [0.25, 1.13]) 
              (evtParticipants, evtParticipantOdds) = unzip eventPayload.eventRecord.predictions
              -- Get the index of the winning participant to use it to index into the evtParticipantOdds list
              winningParticipantIndex =  elemIndex winningParticipant evtParticipants
              -- Get the odds of the winning participant to determine payoutRate
              payoutRate = (!!) evtParticipantOdds winningParticipantIndex
              -- Get the payout amt
              payoutAmt  = betPayload.betSlip.wager * payoutRate

The error we are receiving is the following: " Couldn’t match expected type ‘Int’
with actual type ‘Optional Int’
• In the second argument of ‘(!!)’, namely
‘winningParticipantIndex’
In the expression: (!!) evtParticipantOdds winningParticipantIndex
In an equation for ‘payoutRate’:
payoutRate = (!!) evtParticipantOdds winningParticipantIndextypecheck ".

In the code, we are trying to get the odds number of the winning participant of a given bet, however, when we are trying to get this using the (!!) to index into evtParticipantOdds using the winingParticipantIndex, however that returns a type of Optional Int, rather than a Int. Any suggestions?

@gabmora

Daml doesn’t really have a concept of a cast but instead there are explicit functions to convert. Before we look at those, let’s take a look at how you can do without any library functions:

Let’s say x has value Option Int, you can always pattern match on it:

case x of
  None -> -- do something here
  Some y -> -- do something with y

what exactly you want to do there depends on your usecase ofc. One option would be to just call error in the None case which will abort the transaction. If you are not familiar with pattern matching, take a look at the docs

Pattern matching is great but sometimes a bit more verbose than one would like. That’s where library functions can help.

There are three main ones that are useful here:

fromOptional takes an Optional and a default value and gives you the default value if the Optional was None or the value of the optional otherwise, e.g.,

fromOptional None 0 == 0
fromOptional (Some 5) 0 == 5

fromSomeNote takes an error message and an optional and aborts your transaction with the error message if it was None, e.g.,

fromSomeNote "value X was not present" None

Lastly, there is fromSome. It’s like fromSomeNote but doesn’t allow you to customize the error message. it can be convenient during testing but I would recommend to avoid it in production code. The lack of a good error message can often make it very hard to debug why your transaction gets aborted if you hit the None case.

Thanks very much for reply. Will look into this now. Very much appreciated @cocreature !

1 Like