【问题标题】:how to use merge in daml contract map value?如何在 daml 合约映射值中使用合并?
【发布时间】:2020-11-02 11:38:30
【问题描述】:
MapKey k => (k -> a -> Optional c) -> (k -> b -> Optional c) -> (k -> a -> b -> Optional c) -> Map k a -> Map k b -> Map k c

难以理解语法请提供声明此地图值合并的示例,并简要说明如何通过简单示例构建它

【问题讨论】:

标签: haskell daml


【解决方案1】:

确保您已阅读该函数的 docs

merge 采用三个函数和两个映射。这两个映射具有相同的键类型,但不同的值类型。映射结果表单merge 当然必须有一个单一的值类型,所以我们必须告诉merge 如果发生了什么

  1. 仅存在第一个提供的映射中的值
  2. 仅存在第二个提供的映射中的值
  3. 两个值都存在

例如,假设我们有一个要合并的地图Map Int Text 和一个地图Map Int Bool,我们只是说生成的地图应该表明我们属于上述三种情况中的哪一种。我们可以为此定义一个类型:

data EitherOrBoth a b
  = EOBLeft a
  | EOBRight b
  | EOBBoth (a, b)
    deriving (Eq, Show)

现在我们可以在合并中定义函数来表示“在左侧添加一个值”、“在右侧添加一个值”和“在一个元组中添加两个值”:

mergeWithBoth : (MapKey k) => Map k a -> Map k b -> Map k (EitherOrBoth a b)
mergeWithBoth = merge (\k x -> Some (EOBLeft x)) (\k y -> Some (EOBRight y)) (\k x y -> Some (EOBBoth (x, y)))

使用脚本尝试整个过程:

import Daml.Script
import DA.Next.Map (Map, MapKey, merge, fromList)

data EitherOrBoth a b
  = EOBLeft a
  | EOBRight b
  | EOBBoth (a, b)
    deriving (Eq, Show)

mergeWithBoth : (MapKey k) => Map k a -> Map k b -> Map k (EitherOrBoth a b)
mergeWithBoth = merge (\k x -> Some (EOBLeft x)) (\k y -> Some (EOBRight y)) (\k x y -> Some (EOBBoth (x, y)))

testMerge = script do
  let
    mapIntText : Map Int Text = fromList[(1, "Hello"), (2, "World")]
    mapIntDec : Map Int Bool  = fromList[(2, True), (3, False)]

  assert (mergeWithBoth mapIntText mapIntDec
    == fromList [(1, EOBLeft "Hello"),(2, EOBBoth ("World", True)), EOBRight False)])
  
  return (mergeWithBoth mapIntText mapIntDec)    

【讨论】:

  • 谢谢你的例子,不使用列表可以吗
  • 可以在不通过列表的情况下实例化地图,但这很尴尬。只需链式调用Map.insert,以Map.empty 开头。
【解决方案2】:

如果您有两个具有相同键类型的地图

m1 : Map k a
m2 : Map k b

您可以像这样调用merge 将它们合并成一个地图Map k c

merge f1 f2 f12 m1 m2

在哪里

  • f1 : k -> a -> Optional c 指定如果在 m1 中找到密钥但在 m2 中未找到密钥时要执行的操作。这里f1 传递了m1 中的键及其对应的值。
  • f2 : k -> b -> Optional c 指定如果在 m2 中找到密钥但在 m1 中没有找到密钥时要执行的操作。这里f2 传递了m2 中的键及其对应的值。
  • f12 : k -> a -> b -> Optional c 指定如果在 m1m2 中都找到密钥时要执行的操作。这里f12被传入了key,对应的值在m1,对应的值在m2

在每种情况下,返回None 是您希望结果映射中缺少键。如果您希望密钥存在并关联到值x,则返回Some x

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 2020-03-19
    • 2021-05-06
    • 2021-12-26
    • 2015-07-08
    • 2016-06-08
    • 2012-12-18
    相关资源
    最近更新 更多