我写了这个小程序,我对它的行为有点困惑:
main = sequence $ iterate (printAdd =<<) (pure 0)
printAdd x = do
l <- getLine
let y = x + read l
print y
pure y
我期望它在每次输入一个新整数时打印所有整数的和。它或多或少地工作,但累加器被反复重置为0。这个重置发生在第一次输入之后,在第三次输入之后,在第六次输入之后,以此类推(也就是说,它总是在比以前多输入一次的情况下工作)。
为什么会发生这种情况?
我怎样才能防止它的发生?
iterate
给出了printAdd
逐渐变长的链的列表。
iterate
返回一个列表,其中每个元素都是通过对前一个元素应用函数得到的。在文档中,你可以看到这个插图:
iterate f x == [x, f x, f (f x), ...]
在您的情况下,f = (printAdd =<<)
和x = pure 0
。因此,您的列表看起来像这样:
iterate (printAdd =<<) (pure 0) =
[pure 0, (printAdd =<< pure 0), (printAdd =<< printAdd =<< pure 0), ...]
每个第N个元素将是一个由N个printAdd
调用链接在一起的链,并将0输入到第一个
然后sequence
按顺序执行所有这些元素。第0个什么都不做,第一个读取一个数字并打印出来,第二个读取一个数字,打印出来,然后读取另一个数字,然后打印总和,以此类推。每个第N个元素读取N个数字,并输出它们的滚动和。