Проблема здесь в том, что assert
имеет нечистый эффект, поэтому его нельзя использовать в чистой функции, такой как mergeIou
. Самый простой способ решить эту проблему — изменить mergeIou на тип Iou -> Iou -> Update Iou
и поместить функцию в блок выполнения.
ie.
mergeIou : Iou -> Iou -> Update Iou
mergeIou a b = do
assert $ a.issuer == b.issuer
assert $ a.owner == b.owner
assert $ a.currency == b.currency
pure $ a with amount = a.amount + b.amount
Если вам нужна чистая функция, вы не можете использовать 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
Чтобы помочь с отладкой, я предлагаю вам вместо этого использовать Either
, чтобы вы могли определить, какое из утверждений не удалось:
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
Для более полного обсуждения того, что здесь происходит, я предлагаю вам прочитать мой расширенный ответ на Проблемы с использованием функции getTime, где я обсуждаю концепции чистоты и инкапсуляции взаимодействий реестра в DAML.
person
Recurse
schedule
13.03.2019