GHCi中:sprint命令求值后仍显示_的原因及解决方法
问题原因与解决方法
原因
- 惰性求值与内存回收机制:GHC采用惰性求值策略,
total = sum [1..1000000]初始是一个未求值的thunk(延迟计算的表达式)。执行print total时会强制求值到完整结果,但由于这个结果是一个较大的Integer值,GHC的垃圾回收器在print完成后,会因为没有其他对该值的活跃引用而将其回收,导致total重新回到未求值状态,所以:sprint total仍显示_。而ints = [1..5]的结果体积小,垃圾回收器不会回收,因此:sprint能正常显示值。 - foldl的非严格特性:你定义的
sum = foldl (+) 0使用了非严格的左折叠foldl,它会生成一串嵌套的thunk链,即使求值完成后,GHCi也不会自动将最终结果存回total的绑定中,print操作结束后结果就会被丢弃。
解决方法
- 改用严格折叠函数:导入
Data.List模块后,使用严格左折叠foldl'定义sum,计算过程中会直接求值中间结果,避免生成大量thunk,同时最终结果会被保留在total绑定中:
执行import Data.List (foldl') sum = foldl' (+) 0 total = sum [1..1000000]print total后,:sprint total会显示具体数值。 - 强制保留求值结果:在print操作后,用
seq强制将total与某个值绑定,确保垃圾回收器不会回收它:
之后执行total = sum [1..1000000] print total >> total `seq` return ():sprint total就能看到结果。
内容的提问来源于stack exchange,提问作者Nero gris
相关产品推荐
相关产品推荐

