Я ищу технику, которая позволяет запоминать между последующими вызовами сворачивания списков, которые добавляются в начало.
Я просмотрел библиотеку memoize, но, похоже, она не поддерживает мемоизацию функций высшего порядка, что имеет место для складок.
Я также попробовал эту технику с ленивой оценкой карты результатов, но безрезультатно.
Вот простой пример кода:
module Main where
import Data.Time
printAndMeasureTime :: Show a => a -> IO ()
printAndMeasureTime a = do
startTime <- getCurrentTime
print a
stopTime <- getCurrentTime
putStrLn $ " in " ++ show (diffUTCTime stopTime startTime)
main = do
let as = replicate 10000000 1
printAndMeasureTime $ foldr (-) 0 as -- just to resolve thunks
printAndMeasureTime $ sum as
printAndMeasureTime $ sum (1:as) -- recomputed from scratch, could it reuse previous computation result?
printAndMeasureTime $ length (as)
printAndMeasureTime $ length (1:as) -- recomputed from scratch, could it reuse previous computation result?
и вывод:
0
in 1.125098223s
10000000
in 0.096558168s
10000001
in 0.104047058s
10000000
in 0.037727126s
10000001
in 0.041266456s
Времена подсказывают, что складки рассчитываются с нуля. Есть ли способ заставить последующие сгибы повторно использовать предыдущие результаты сгиба?