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

Haskell中iterate组合IO操作出现累加器反复重置问题求解

现象原因
  • 核心原因是Haskell中的IO动作是待执行的副作用指令,而非执行后的结果值,嵌套IO动作每次被调用时都会从头完整执行所有内层逻辑。
  • 你的代码中iterate (printAdd =<<) (pure 0)会生成无限嵌套的IO动作列表,第k个元素对应k-1层嵌套,执行时会完整跑k-1次printAdd,每次都从pure 0开始计算。
  • sequence会按顺序执行列表中所有IO动作:
    1. 执行第2个元素时运行1次printAdd,对应第1次输入
    2. 执行第3个元素时先重新运行1次printAdd 0(累加器重置为0,对应第2次输入),再运行1次外层printAdd(对应第3次输入)
    3. 执行第4个元素时先重新运行1次printAdd 0(累加器再次重置,对应第4次输入),再依次运行外层两层printAdd(对应第5、6次输入)
  • 重置出现的位置正好是三角数1、3、6、10...,和你观察到的现象完全吻合。
修复方案

你需要的是可传递前序执行结果的无限循环,不需要重复执行之前的IO逻辑,有两种常见实现方式:

递归实现(无额外依赖)

main = loop 0
  where
    loop currentSum = do
      inputStr <- getLine
      let newSum = currentSum + read inputStr
      print newSum
      loop newSum

函数式风格实现(使用标准库工具)

调用Control.Monad下的iterateM_,它会自动传递上一步的返回值作为下一步的输入,不会重复执行前置逻辑:

import Control.Monad (iterateM_)

main = iterateM_ printAdd 0

printAdd x = do
  l <- getLine
  let y = x + read l
  print y
  pure y

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:09:02