Аз съм съвсем нов в Haskell и се опитвам да обясня как работи мързеливият израз на последователностите на Фибоначи.
Знам, че това е задавано и преди, но нито един от отговорите не адресира проблем, който имам с визуализирането на резултата.
Кодът е каноничният, използващ zipWith
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Разбирам следното:
zipWith
буквално закопчава два списъка заедноtail
грабва всички елементи от списъка освен първия- Haskell препраща към изчислените данни „предстоящи“ като
thunks
.
Доколкото разбирам, първо добавя [0,1,<thunk>]
и [1,<thunk>]
, използвайки zipWith (+)
, за да даде [1,<thunk>]
. Така че сега имате
fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs)
Много препратки, които съм търсил в Google, след това продължиха да „визуализират“ реда по-горе като
fibs = 0 : 1 : 1 : zipWith (+) [1,1,<thunk>] ([1,<thunk>]).
Въпросът ми е следният:
Защо компонентът fibs
в горния ред съответства само на [1,1,<thunk>]
вместо на [0,1,1,<thunk>]
?
Не трябва ли fibs
да съдържа целия списък плюс <thunk>
?
take 3 fibs
) . По този начин няма объркване между една и съща част от данните, достъпна два пъти (чрез едно и също име), или две равни части от данни (всеки със собствено име). - person Will Ness   schedule 11.11.2014fibs = 0 : 1 : 1 : zipWith (+) (drop 1 $ fibs) (drop 1 $ tail fibs)
, защото в този момент сме напреднали с една стъпка по списъка. и в това се крие отговорът на въпроса ти. - person Will Ness   schedule 03.09.2019