这是一个打印前40个斐波那契数字的小程序 三次 -
ghc Main.hs
如果我使用run
编译它,则“运行”的计算部分由GHC保存,因此执行ghc -O2 Main.hs
三次所需的时间与运行一次的时间大致相同。这真是一个惊喜!我的印象是monadic效果不会像这样自动记忆。
另外,如果我用unsafePerformIO
编译它,那么记忆就会丢失。 (至少在我的机器上使用ghc 7.10.3)
如何预测什么时候会被记忆?某处有一些记录在案的经验法则吗?这与<outputDirectory>
等有何关系?
答案 0 :(得分:1)
这里run
是一个常量表达式。因此,像任何其他常量表达式一样,它只被评估一次。哦,它编码的I / O操作得到执行三次,但表达式(或者更确切地说,它的子表达式)只评估一次。
我的猜测(这只是猜测)是不命名它可能会导致每次重新评估它。如在
main = do
mapM_ (print . fib) [1..40]
mapM_ (print . fib) [1..40]
mapM_ (print . fib) [1..40]
可能会多次评估它。但我不是百分之百确定。
现在,如果run
是功能:
main = run 40 >> run 40 >> run 40
where
run n = mapM_ (print . fibs) [1..n]
然后它可能多次评估。我认为GHC会避免像这样保留任意函数调用的结果。