在 DAML 选择中执行多个更新

Exercising multiple updates within DAML choice

在 DAML 中是否可以使用类似映射的函数来迭代 contractid 列表,检索它们并对每个执行选择?这似乎在 DAML 中受到限制,因为在执行选择时所有内容都需要包装在单个更新中。

这是我尝试过的示例(注意问题):

exerciseChoice: ContractId ContractB -> Update (ContractId ContractB)
exerciseChoice contractB = do (exercise contractB UpdateB with newText = "test")

template ContractA
  with
    party : Party
    contracts: [ContractId ContractB]
  where
    signatory party

    controller party can
      nonconsuming UpdateA : [Update (ContractId ContractB)]
        with newText : Text
        do  
          --   a <- create ContractB with party = party; text = newText
          --   a2 <- exerciseChoice a
          --   return [a2] #these lines work fine

          return map exerciseChoice contracts
          -- #this doesn't work due to DAML implicitly adding Update before return definition
          -- i.e. DAML expects type 'Update [Update (ContractId ContractB)]' based on this signature
          -- we need a function which converts something like: 
          -- '[Update (ContractId ContractB)] -> Update [ContractId ContractB]'

template ContractB
  with
    party : Party
    text: Text
  where
    signatory party

    controller party can
      UpdateB: ContractId ContractB
        with newText: Text
          do create this with text = newText

如果这个问题可以解决,您能否也解释一下为什么在 DAML 中返回多个元组时它们似乎隐式地从 (Update (ContractId A), Update (ContractId B)) 转换为 Update (ContractId A, ContractId B)

函数 map 的类型为 (a -> b) -> [a] -> [b],因此 map exerciseChoice contracts 的类型为 [Update (ContractId ContractB)]。将动作列表变成单个动作在概念上很简单。结果动作是按顺序执行列表中每个动作的动作。事实上,有一个函数:sequence : (Applicative m) => [m a] -> m [a]Update 是一个应用程序,所以你可以写 sequence (map exerciseChoice contracts)。然而,这是一项如此常见的任务,以至于有一个专门的功能 mapA : (Applicative m) => (a -> m b) -> [a] -> m [b]

mapA exerciseChoice contracts 应该可以解决问题。