You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在Pact中调用纯函数的顺序会改变执行结果?

问题原因及解决方案

原因分析

你遇到的问题核心在于**select返回的是惰性求值的序列(游标),而非已固化的列表**:

  • 在sum-claims函数内部,两次fold操作都会遍历这个惰性序列;
  • 当在同一个函数调用上下文(比如pretty-read-lock2/3的let*块)中连续调用两次sum-claims时,底层查询机制可能存在游标未重置、会话级结果累积的特性,导致第二次select重复读取了第一次的记录,最终累加出两倍的结果;
  • 单独调用sum-claims时,函数执行完毕后上下文销毁,不会触发重复读取,因此结果正确。

从你的测试结果也能印证这点:不管先调用哪个sum-claims,第二个调用的结果都会是正确值的两倍。

解决方案

将select返回的惰性序列物化为具体的列表,确保每次查询的结果被固定下来,避免后续操作时重复读取。修改sum-claims中的records定义,用list函数包裹select的结果:

(defun sum-claims (lock-id:string coin-type:string)
  "Returns the total 'claimed' and 'coin-price' sums for the given lock-id and coin."
  (let* (
         ; 把select结果转为列表,固化查询结果
         (records
           (list
             (if (= "KDA" coin-type)
               (select claim-table    (where "lock-number" (= lock-id)))
               (select external-claim-table
                       (and? (where "lock-number" (= lock-id))
                             (where "coin-type"         (= coin-type))))))
         (total-claimed
           (fold (+) 0.0
             (map (lambda (r) (at 'claimed     r)) records)))
         (total-coin-price
           (fold (+) 0.0
             (map (lambda (r) (at 'coin-price  r)) records)))
        )
    { "total-claimed":  total-claimed
    , "coin-price": total-coin-price })
)

修改后,每次select的结果都会被转换成固定列表,无论是函数内部的两次fold,还是外部连续调用sum-claims,都会基于正确的单次查询结果计算,不会再出现数值翻倍的问题。

内容的提问来源于stack exchange,提问作者Nexion21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:05:02