Причина, по которой выполнение этой функции искажается при сканировании, заключается в том, что она использует множественную рекурсию, например. функция вызывает себя дважды при каждом рекурсивном вызове. Это означает, что во время выполнения этой рекурсивной функции происходят повторные вычисления и что временная сложность вычислений возрастает экспоненциально по мере увеличения размера входов.
Последствия этого более заметны при больших входных значений, как 20
Давайте посмотрим на вызов к сетке (5, 5).
Это расширяется следующим образом.
grid(5, 5)
grid(4, 5) + grid(5, 4)
(grid(3, 5) + grid(4, 4)) + (grid(4, 4) + grid(5, 3))
((grid(2, 5) + grid(3, 4)) + (grid(4, 3) + grid(3, 4))) +
((grid(3, 4) + grid(4, 3)) + (grid(4, 3) + grid(5, 2)))
...and so on
Как вы можете видеть, что вещи получить из рук быстро даже при малых значениях х и у сетки (3, 4) и сетка (4, 3) рассчитываются несколько раз. Как было сказано ранее, решение, использующее zipWith, будет намного более эффективным.
Спасибо. Это помогло. Я использовал zipWith .. но то, что я придумал, кажется субоптимальным, поскольку есть второй вход для созданной функции nextpascal, которая на самом деле не используется .. nextpascal [] _ = [] nextpascal (x: xs) _ = 1: (zipWith (+) (x: xs) xs) ++ [1] allpascal :: [[Integer]] allpascal = ([1,1]): zipWith (nextpascal) allpascal (repeat []) square n = head (drop n (last (take (2 * n) allpascal))) – brander