6
心下面的程序:是否有可能改善功能容器的渐近性?
data Box = Box Int
initial = Box 1
stepper (Box x) = Box (x+1)
getter (Box x) = x
run 0 state = []
run n state = getter state : run (n-1) (stepper state)
main = print $ sum $ run 50000000 initial
这里,run
显然是线性的,因为它是一个递归从0
到n
和stepper
是恒定的时间函数。您可以通过更改常数来验证 - 运行时间线性比例变化。现在,考虑到这一点代码:
initial' box = box 1
stepper' box box_ = box (\ x -> (box_ (x+1)))
getter' box = box (\ x -> x)
run' 0 state = []
run' n state = getter' state : run' (n-1) (stepper' state)
main = print $ sum $ run' 8000 initial'
这是非常相同的算法上面的程序,唯一改变的事情是,一个功能是用作容器,而不是数据类型。然而,它是二次的:stepper' state
永远不会执行,创建一个越来越大的thunk,并在每个步骤重新评估。无论常量大小不同,两个程序都需要相同的时间运行。我相信第二个程序可以固定的意思是评估一个术语到正常形式,但是GHC没有提供,所以,是否有可能修复第二个程序,因此它不是二次的?
你让我想起'$!'的存在,这会很有用。 – MaiaVictor