Проблема здесь в том, что assert
имеет нечистый эффект, поэтому его нельзя использовать в чистой функции, такой как mergeIou
.Самый простой способ решить эту проблему - изменить mergeIou на тип Iou -> Iou -> Update Iou
и поместить функцию в do-блок.
т.е..
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.