user1108: I have 4 different Datum Data Types in my script because for 4 different use cases in my script.
data FundCreationDatum = FundCreationDatum
  { vFundOwner :: PaymentPubKeyHash,
    vPrizeAmount :: Integer,
    vProjectLabel :: [BuiltinByteString],
    vPrizeDistributionRatio :: [Integer]
  }

data ProjectSubmitDatum = ProjectSubmitDatum
  { vProjectOwner :: PaymentPubKeyHash,
    vProjectRegistrationFee :: Integer,
    vProjectCategory :: BuiltinByteString,
    vFundPayIdentifier :: PaymentPubKeyHash
  }

data VotingActionDatum = VotingActionDatum
  { vProjectToVote :: PaymentPubKeyHash,
    vVoterPayAddress :: PaymentPubKeyHash,
    vAdaLovelaceValue :: Integer,
    vVoteFundIdentifier :: PaymentPubKeyHash,
    vActionName :: BuiltinByteString
  }
  deriving (Show)

data ConToMatchPool = ConToMatchPool
  { vFundAddress :: PaymentPubKeyHash,
    vPrizeFund :: Integer
  }
  deriving (Show)

I then bundled the 4 data types into a single data type with the Maybe monad.
data QuadraDatum = QuadraDatum
  { qCreateFund :: (Maybe FundCreationDatum),
    qVoting :: (Maybe VotingActionDatum),
    qSubProject :: (Maybe ProjectSubmitDatum),
    qContrPool :: (Maybe ConToMatchPool)
  }

I am trying to send a utxo with datum attached like this.
start cp = do 
  let dat = QuadraDatum qContrPool
            {vFundOwner = cpFundOwner cp
            ,vPrizeAmount = cpPrizeAmount cp
            ,vProjectLabel = cpProjectLabel cp
            ,vPrizeDistributionRatio = cpPrizeDistributionRatio cp
            }
      tx = Constraints.mustPayToTheScript dat $ Ada.lovelaceValueOf $ (cpPrizeAmount cp)  
  ledgerTx <- submitTxConstraints typedValidator tx
  void $ awaitTxConfirmed $ getCardanoTxId ledgerTx

I am getting the following error
 error:
    • Couldn't match expected type ‘Maybe FundCreationDatum’
                  with actual type ‘FundCreationDatum’


user833: let's say we have a Maybe Integer type, then the value must be assigned as either Just 3 or Nothing.
Directly assigning  it as 3 won't work.
So your QuadraDatum should be   created as
  let dat = QuadraDatum 
              (Just qContrPool)
              (Just {vFundOwner = cpFundOwner cp
                  ,vPrizeAmount = cpPrizeAmount cp
                  ,vProjectLabel = cpProjectLabel cp
                  ,vPrizeDistributionRatio = cpPrizeDistributionRatio cp
               }) 
               Nothing
               Nothing

Also, better approach is to use multiple constructors something like this
data QuadraDatum = FundCreationDatum
  { 
    vPrizeAmount :: Integer,
    ...
  }|
  ProjectSubmitDatum
    { 
      vProjectRegistrationFee :: Integer,
      ...
    }
  deriving (Show)



1108: <p>I have 4 different Datum Data Types in my script because for 4 different use cases in my script.</p>
<pre><code>data FundCreationDatum = FundCreationDatum
  { vFundOwner :: PaymentPubKeyHash,
    vPrizeAmount :: Integer,
    vProjectLabel :: [BuiltinByteString],
    vPrizeDistributionRatio :: [Integer]
  }

data ProjectSubmitDatum = ProjectSubmitDatum
  { vProjectOwner :: PaymentPubKeyHash,
    vProjectRegistrationFee :: Integer,
    vProjectCategory :: BuiltinByteString,
    vFundPayIdentifier :: PaymentPubKeyHash
  }

data VotingActionDatum = VotingActionDatum
  { vProjectToVote :: PaymentPubKeyHash,
    vVoterPayAddress :: PaymentPubKeyHash,
    vAdaLovelaceValue :: Integer,
    vVoteFundIdentifier :: PaymentPubKeyHash,
    vActionName :: BuiltinByteString
  }
  deriving (Show)

data ConToMatchPool = ConToMatchPool
  { vFundAddress :: PaymentPubKeyHash,
    vPrizeFund :: Integer
  }
  deriving (Show)
</code></pre>
<p>I then bundled the 4 data types into a single data type with the Maybe monad.</p>
<pre><code>data QuadraDatum = QuadraDatum
  { qCreateFund :: (Maybe FundCreationDatum),
    qVoting :: (Maybe VotingActionDatum),
    qSubProject :: (Maybe ProjectSubmitDatum),
    qContrPool :: (Maybe ConToMatchPool)
  }
</code></pre>
<p>I am trying to send a utxo with datum attached like this.</p>
<pre><code>start cp = do 
  let dat = QuadraDatum qContrPool
            {vFundOwner = cpFundOwner cp
            ,vPrizeAmount = cpPrizeAmount cp
            ,vProjectLabel = cpProjectLabel cp
            ,vPrizeDistributionRatio = cpPrizeDistributionRatio cp
            }
      tx = Constraints.mustPayToTheScript dat $ Ada.lovelaceValueOf $ (cpPrizeAmount cp)  
  ledgerTx &lt;- submitTxConstraints typedValidator tx
  void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
</code></pre>
<p>I am getting the following error</p>
<pre><code> error:
    • Couldn't match expected type ‘Maybe FundCreationDatum’
                  with actual type ‘FundCreationDatum’
</code></pre>
 833: <p>let's say we have a <code>Maybe Integer</code> type, then the value must be assigned as either <code>Just 3</code> or <code>Nothing</code>.</p>
<p>Directly assigning  it as <code>3</code> won't work.</p>
<p>So your <code>QuadraDatum</code> should be   created as</p>
<pre><code>  let dat = QuadraDatum 
              (Just qContrPool)
              (Just {vFundOwner = cpFundOwner cp
                  ,vPrizeAmount = cpPrizeAmount cp
                  ,vProjectLabel = cpProjectLabel cp
                  ,vPrizeDistributionRatio = cpPrizeDistributionRatio cp
               }) 
               Nothing
               Nothing
</code></pre>
<p>Also, better approach is to use multiple constructors something like this</p>
<pre><code>data QuadraDatum = FundCreationDatum
  { 
    vPrizeAmount :: Integer,
    ...
  }|
  ProjectSubmitDatum
    { 
      vProjectRegistrationFee :: Integer,
      ...
    }
  deriving (Show)

</code></pre>
