Рассмотрим две следующие реализации бесконечной последовательности Фибоначчи:
fibsA :: Num a => [a]
fibsA = 0:1:(zipWith (+) fibsA (tail fibsA))
fibsB :: [Integer]
fibsB = 0:1:(zipWith (+) fibsB (tail fibsB))
В GHCI выполнение fibsB !! k
выполняется намного быстрее, чем выполнение fibsA !! k
.
В частности, кажется, что значения fibsA
непрерывно пересчитываются (не сохраняются или сохраняются).
Кроме того, когда сигнатура типа опущена, GHCI :t
показывает, что она [Integer]
, и функция выполняет соответственно.
Это также происходит в скомпилированном коде (ghc -O3 Fibs.hs
).
Почему это так, что Integer
намного быстрее, чем Num a => a
?