Daml.Finance Transfer exercise

Hello everyone.
I am trying to do this exercise : toInterfaceContractId

which is about spliting a holding in order to transfer one of them to a receiver account and keep the rest in the sender account.

I have updated the provided Accept choice in the Transfer.Request template as such :
First I have imported the DA.List library : import DA.List (head)

choice Accept : ContractId Holding.I
with
holdingCid : ContractId Holding.I
controller currentOwner
do
– Sanity checks
holding ← fetch holdingCid
assert (getAmount holding >= amount)
getInstrument holding === instrument

    -- DO_TRANSFER_BEGIN
    let fungibleCid = coerceInterfaceContractId @Fungible.I holdingCid

    splitResult <- exercise fungibleCid Fungible.Split with
      amounts = [amount]

    let holdingToTransfer = head splitResult.splitCids

    let transferableCid = toInterfaceContractId @Transferable.I holdingToTransfer

    newTransferableCid <- exercise transferableCid Transferable.Transfer with
      actors = fromList [currentOwner, receiverAccount.owner]
      newOwnerAccount = receiverAccount

    pure $ toInterfaceContractId @Holding.I newTransferableCid
    -- DO_TRANSFER_END

I ma getting the following error when running “daml.start” :

daml/Workflow/Transfer.daml:48:67: error:
    • Couldn't match expected type ‘ContractId t1’
                  with actual type ‘[a0] -> a0’
    • Probable cause: ‘head’ is applied to too few arguments
      In the second argument of ‘toInterfaceContractId’, namely ‘head’
      In the expression:
        toInterfaceContractId
          @Fungible.I head (getField @"splitCids" splitResult)
      In an equation for ‘holdingToTransfer’:
          holdingToTransfer
            = toInterfaceContractId
                @Fungible.I head (getField @"splitCids" splitResult)

Can anyone help me out?

tl;dr

Try one of the following (which are equivalent):

holdingToTransfer
  = toInterfaceContractId
      @Fungible.I (head (getField @"splitCids" splitResult))
holdingToTransfer
  = toInterfaceContractId
      @Fungible.I $ head (getField @"splitCids" splitResult)

More complete answer

The error says that something is wrong with the following:

holdingToTransfer
  = toInterfaceContractId
      @Fungible.I head (getField @"splitCids" splitResult)

The error says:

Couldn't match expected type ‘ContractId t1’
            with actual type ‘[a0] -> a0’

Let’s pick this apart.

Couldn’t match expected type ‘ContractId t1’"

The above says that the toInterfaceContractId function is expecting a ContractId as an input.

with actual type ‘[a0] → a0’

The above says that what is actually being passed to the toInterfaceContractId function is a ‘[a0] -> a0’ value (not the expected ContractId value).

The head function (with signature [a0] -> a0) is being passed to the toInterfaceContractId function. What you want is for the head function to be called with the remainder of the line (and then that result passed to toInterfaceContractId). Adding parentheses or the $ operator should fix this error.

1 Like

thank you very much @WallaceKelly , it works now!