Я заметил, что иногда чистые функции Haskell каким-то образом кэшируются: если я дважды вызываю функцию с теми же параметрами, второй раз результат вычисляется в мгновение ока.
- Почему это происходит? Это функция GHCI или что?
- Могу ли я полагаться на это (то есть: могу ли я детерминистически знать, будет ли кэшировано значение функции)?
- Могу ли я принудительно отключить эту функцию для некоторых вызовов функций?
В соответствии с комментариями, вот пример, который я нашел в Интернете:
isPrime a = isPrimeHelper a primes
isPrimeHelper a (p:ps)
| p*p > a = True
| a `mod` p == 0 = False
| otherwise = isPrimeHelper a ps
primes = 2 : filter isPrime [3,5..]
Я ожидал, прежде чем запускать его, довольно медленно, так как он продолжает получать доступ к элементам primes
без явного кэширования их (таким образом, если эти значения не кэшированы где-то, их нужно будет перечитать много раз). Но я был неправ.
Если я устанавливаю +s
в GHCI (для печати статистики времени/памяти после каждой оценки) и дважды оцениваю выражение primes!!10000
, это то, что я получаю:
*Main> :set +s
*Main> primes!!10000
104743
(2.10 secs, 169800904 bytes)
*Main> primes!!10000
104743
(0.00 secs, 0 bytes)
Это означает, что по крайней мере primes !! 10000
(или лучше: весь список primes
, так как также primes!!9999
не займет времени) должен быть кэширован.