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