如何在DAML中断言函数内部的条件?

如何在DAML中断言函数内部的条件?,daml,Daml,我有以下代码: 模板Iou 具有 发行人:缔约方 业主:第三方 金额:十进制 货币:文本 哪里 签字发行人 合并借据:借据->借据->借据 合并a b= --断言$a.issuer==b.issuer --断言$a.owner==b.owner --断言$a.currency==b.currency a金额=a金额+b金额 当我取消对任何断言的注释时,会出现以下错误: * Couldn't match expected type `Iou' with actual type `m0 ()'

我有以下代码:

模板Iou
具有
发行人:缔约方
业主:第三方
金额:十进制
货币:文本
哪里
签字发行人
合并借据:借据->借据->借据
合并a b=
--断言$a.issuer==b.issuer
--断言$a.owner==b.owner
--断言$a.currency==b.currency
a金额=a金额+b金额
当我取消对任何断言的注释时,会出现以下错误:

* Couldn't match expected type `Iou' with actual type `m0 ()'
    * In the expression:
        assert
          $ (DA.Internal.Record.getField @"issuer" a)
...

我做错了什么?

这里的问题是
assert
有一种不纯的效果,所以不能用在纯文本中 函数类似于
mergeIou
。解决这个问题最简单的方法就是改变 合并Iou,使其具有类型
Iou->Iou->Update Iou
,并将函数置于 不要挡

如果需要纯函数,则不能使用
assert
。最简单的 另一种方法是使用
Optional
在类型中明确故障:

mergeIou : Iou -> Iou -> Optional Iou
mergeIou a b = do
  unless (a.issuer == b.issuer) None
  unless (a.owner == b.owner) None
  unless (a.currency == b.currency) None
  pure $ a with amount = a.amount + b.amount
为了帮助调试,我建议您使用
或者
,这样您就可以
确定哪些断言失败:

mergeIou : Iou -> Iou -> Either Text Iou
mergeIou a b = do
  unless (a.issuer == b.issuer) $ Left "IOU issuers did not match"
  unless (a.owner == b.owner) $ Left "IOU owners did not match"
  unless (a.currency == b.currency) $ Left "IOU currencies did not match"
  pure $ a with amount = a.amount + b.amount
为了更全面地讨论这里到底发生了什么,我建议你 请阅读我的扩展答案 在这里,我讨论了纯度和封装的概念
DAML中的交互作用。

这里的问题是,
assert
具有不纯净的效果,因此不能在纯文本中使用 函数类似于
mergeIou
。解决这个问题最简单的方法就是改变 合并Iou,使其具有类型
Iou->Iou->Update Iou
,并将函数置于 不要挡

如果需要纯函数,则不能使用
assert
。最简单的 另一种方法是使用
Optional
在类型中明确故障:

mergeIou : Iou -> Iou -> Optional Iou
mergeIou a b = do
  unless (a.issuer == b.issuer) None
  unless (a.owner == b.owner) None
  unless (a.currency == b.currency) None
  pure $ a with amount = a.amount + b.amount
为了帮助调试,我建议您使用
或者
,这样您就可以
确定哪些断言失败:

mergeIou : Iou -> Iou -> Either Text Iou
mergeIou a b = do
  unless (a.issuer == b.issuer) $ Left "IOU issuers did not match"
  unless (a.owner == b.owner) $ Left "IOU owners did not match"
  unless (a.currency == b.currency) $ Left "IOU currencies did not match"
  pure $ a with amount = a.amount + b.amount
为了更全面地讨论这里到底发生了什么,我建议你 请阅读我的扩展答案 在这里,我讨论了纯度和封装的概念
DAML中的交互。

如果利用DAML的
ActionFail
类型类,实际上有一种方法可以从@Recurse的答案一次过定义所有三个版本的
mergeIou

mergeIou : ActionFail m => Iou -> Iou -> m Iou
mergeIou a b = do
  unless (a.issuer == b.issuer) $ fail "IOU issuers did not match"
  unless (a.owner == b.owner) $ fail "IOU owners did not match"
  unless (a.currency == b.currency) $ fail "IOU currencies did not match"
  pure $ a with amount = a.amount + b.amount

如果您利用DAML的
ActionFail
类型类,实际上有一种方法可以通过@Recurse的答案一次性定义所有三个版本的
mergeIou

mergeIou : ActionFail m => Iou -> Iou -> m Iou
mergeIou a b = do
  unless (a.issuer == b.issuer) $ fail "IOU issuers did not match"
  unless (a.owner == b.owner) $ fail "IOU owners did not match"
  unless (a.currency == b.currency) $ fail "IOU currencies did not match"
  pure $ a with amount = a.amount + b.amount