Multiple conditions - if... else

Hello everyone,

I started my code from a slightly easier topic (the weighted selection) before starting with the random selection.

I am writing a template to create a contract with a score and an automatic text note depending on the score. I have read the published topics regarding “if…else” conditions" and the documentation, but I still cannot understand where I am wrong.

Could someone please help? Sorry if I keep pestering all of you with my questions! Your help is so precious to me! :pray: :pray: :pray: :pray: :pray:

template GiveScore

    with 
        mainEntity : Party
        score : Int
        scoreNotes : Text
        entity: Party

    where 
        signatory mainEntity 
        observer entity
        ensure (score>=0)

        choice AssignScore
            : GiveScoreId
            with 
                weightedScore :Int
                scoreComment: Text

            controller mainEntity
            
            do 
                assertMsg "The score must be an integer between 1 & 10" $
                    (weightedScore>=0 && weightedScore<=10)

                if (weightedScore>=0 && weightedScore<=4 scoreComment == "You can improve") then do
                    create this with 
                        score = weightedScore
                        scoreNotes = scoreComment  
                    
                    if (weightedScore>4 && weightedScore<=6 scoreComment == "You are average") then do
                        create this with 
                            score = weightedScore
                            scoreNotes = scoreComment  

                    else if (weightedScore>6 && weightedScore<=10 scoreComment == "You are great ")  then do
                        create this with 
                            score = weightedScore
                            scoreNotes = scoreComment

In Daml you always need to have an else block in an if since it it an expression not a statement so you need to define the value of the expression in both cases. You can ofc error out in one of them or do nothing (e.g. pure ()) if that matches the expected type.

In your example, this would mean something like this:

template GiveScore
    with 
        mainEntity : Party
        score : Int
        scoreNotes : Text
        entity: Party

    where 
        signatory mainEntity 
        observer entity
        ensure (score>=0)

        choice AssignScore
            : GiveScoreId
            with 
                weightedScore :Int
                scoreComment: Text

            controller mainEntity
            
            do 
                assertMsg "The score must be an integer between 1 & 10" $
                    (weightedScore>=0 && weightedScore<=10)

                if weightedScore>=0 && weightedScore<=4 && scoreComment == "You can improve"
                  then
                    create this with 
                        score = weightedScore
                        scoreNotes = scoreComment  
                  else if (weightedScore>4 && weightedScore<=6 && scoreComment == "You are average") 
                    then do
                        create this with 
                            score = weightedScore
                            scoreNotes = scoreComment  

                    else if (weightedScore>6 && weightedScore<=10 && scoreComment == "You are great ") 
                      then do
                        create this with 
                            score = weightedScore
                            scoreNotes = scoreComment
                      else do
                        abort "Impossible: weightedScore was not between 0 and 10"

Those nested if expressions can get somewhat difficult to read so there is a feature called MultiWayIf which allows you to combine them into a single if statement where the first condition that is True will be the one that is used. In your example that would look like this:

{-# LANGUAGE MultiWayIf #-}
module Main where

type GiveScoreId = ContractId GiveScore

template GiveScore
    with 
        mainEntity : Party
        score : Int
        scoreNotes : Text
        entity: Party

    where 
        signatory mainEntity 
        observer entity
        ensure (score>=0)

        choice AssignScore
            : GiveScoreId
            with 
                weightedScore :Int
                scoreComment: Text

            controller mainEntity
            
            do 
                if | weightedScore>=0 && weightedScore<=4 && scoreComment == "You can improve" ->
                      create this with 
                        score = weightedScore
                        scoreNotes = scoreComment  
                    | weightedScore>4 && weightedScore<=6 && scoreComment == "You are average" ->
                        create this with 
                            score = weightedScore
                            scoreNotes = scoreComment  

                    | weightedScore>6 && weightedScore<=10 && scoreComment == "You are great " ->
                        create this with 
                            score = weightedScore
                            scoreNotes = scoreComment
                    | otherwise -> abort "The score must be an integer between 0 and 10"

Hi Moritz,

This is incredibly clear!!! Thank you ever so much for your time and support!!!
I love learning Daml. Without you all and this wonderful community, it would be impossible for me to progress. I love you all!

Thank you ever so much, Moritz. I wish you a wonderful weekend!! :pray: :pray: :pray: :pray: :smiley: :smiley:

1 Like