В Haskell канонический zip с реализацией функции Фибоначчи:
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
Мне сложно проанализировать сложность этого времени (выдумки! N).
Пытаясь написать это на бумаге, сначала я подумал, что это экспоненциально.
Тогда O (n ^ 2), но я понятия не имею, как это происходит, чтобы быть линейным.
Почему я думаю, что это линейно: https://wiki.haskell.org/The_Fibonacci_sequence#Canonical_zipWith_implementation
Также я написал другой код:
fibs :: [Integer]
fibs = inc (0,1) where inc (a,b) = a : inc (b,a+b)
Это, я считаю, явно O (n). Но используя опцию: set + s в ghci, я вижу, что реализация zipWith явно превосходит мою.
Примечание: я знаю, что для сложения n-го и (n-1) -го числа Фибоначчи требуется O (n) время. Таким образом, во время тестирования я сделал базовый вариант, то есть первые два элемента 0: 0.
Временные сложности упоминаются с использованием того же предположения.
Было бы здорово, если бы я мог получить некоторую помощь в отслеживании этих вызовов функций. Мне интересно узнать, когда была вызвана функция, и, возможно, напечатать что-нибудь, чтобы сообщить мне, что происходит.
Моя неудачная попытка:
zipWith' = trace ("Called zipWith") (zipWith)
add' a b = trace (show a ++ " + " ++ (show b)) (add a b)
fibs = trace ("Called fibs") (1 : 1 : zipWith (+) fibs (tail fibs))
Это не работает. Заявления напечатаны ровно один.
За исключением добавления, которое работает отлично, на удивление.
Я хочу знать, сколько раз и в каком порядке вызывались эти функции.