You can use the functions in DA.Next.Map
to manipulate maps. Here is a complete working example which I hope can shed some light on syntax and simple use-cases:
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", ["it was not very good"]),
("item2", ["this is great!", "I can't stop raving about it"])]
Tested on SDK 1.6.0.
I've also recently answered a possibly related question on the DAML forum, where I have a few more examples of using the functions in DA.Next.Map. Maybe that can help, too.