如何仅更新daml合同中的Map值?

问题描述

Datatype detail:
  type1: Text
  type2: [detail2]

Datatype detail2:
  type1: Text

template A
with 
    consumerName: Text
    producerName : Text
    details : Map Text detail

create A with consumerName,producerName,details

现在需要使用具有多个键值的新的Details(地图文本数据类型)更新合同旧的Details(地图文本数据类型)。如何使用合并来实现此目的而无需执行多个合同更新或其他任何解决方案?

解决方法

您可以使用DA.Next.Map中的功能来操作地图。这是一个完整的工作示例,我希望可以对语法和简单用例有所了解:

module Main where

import Daml.Script
import qualified DA.Next.Map as Map
import DA.Next.Map (Map)

template Comments
  with
    producer: Party
    consumer: Party
    productComments: Map Text [Text]
  where
    signatory producer
    observer consumer
    preconsuming choice AddComment: ContractId Comments
      with productName: Text,comment: Text
      controller consumer
      do
        create this with productComments = addComment productComments productName comment
    nonconsuming choice ReadComments: Map Text [Text]
      with reader: Party
      controller reader
      do return productComments

addComment: Map Text [Text] -> Text -> Text -> Map Text [Text]
addComment prev item newComment = case Map.lookup item prev of
  -- If the key is not in the map yet,we just add the comment
  None -> Map.insert item [newComment] prev
  -- If there are comments already,add to the end
  Some existingComments -> Map.insert item (existingComments ++ [newComment]) prev

setup : Script ()
setup = script do
  alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
  bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")

  id1 <- submit bob do
    createCmd Comments
      with producer = bob
           consumer = alice
           productComments = mempty -- start with an empty map
  map1 <- submit alice do exerciseCmd id1 (ReadComments alice)
  assert $ map1 == Map.fromList []

  id2 <- submit alice do exerciseCmd id1 (AddComment "item1" "it was not very good")
  map2 <- submit alice do exerciseCmd id2 (ReadComments alice)
  assert $ map2 == Map.fromList [("item1",["it was not very good"])]

  id3 <- submit alice do exerciseCmd id2 (AddComment "item2" "this is great!")
  map3 <- submit alice do exerciseCmd id3 (ReadComments alice)
  assert $ map3 == Map.fromList [("item1",["it was not very good"]),("item2",["this is great!"])]

  id4 <- submit alice do exerciseCmd id3 (AddComment "item2" "I can't stop raving about it")
  map4 <- submit alice do exerciseCmd id4 (ReadComments alice)
  assert $ map4 == Map.fromList [("item1",["this is great!","I can't stop raving about it"])]

在SDK 1.6.0上进行了测试。

我最近也回答了a possibly related question on the DAML forum,在这里我有更多使用DA.Next.Map中的函数的示例。也许也有帮助。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...