znalazłem to oświadczenie podczas studiów funkcyjną reagującą Programowanie, z "Plugging a Space Leak with an Arrow" przez Hai Liu i Pawła Hudák (strona 5):Dlaczego rekursywne `let` make space effcient?
Suppose we wish to define a function that repeats its argument indefinitely: repeat x = x : repeat x or, in lambdas: repeat = λx → x : repeat x This requires O(n) space. But we can achieve O(1) space by writing instead: repeat = λx → let xs = x : xs in xs
Różnica tutaj wydaje się niewielka, ale niezwykle skłania efektywności przestrzeni. Dlaczego i jak to się dzieje? Najlepszym przypuszczenie Zrobiłem to ocenić je ręcznie:
r = \x -> x: r x
r 3
-> 3: r 3
-> 3: 3: 3: ........
-> [3,3,3,......]
Jak wyżej, musimy tworzyć nieskończone nowe łącznikami dla tych rekursji. Wtedy staram się ocenić drugi:
r = \x -> let xs = x:xs in xs
r 3
-> let xs = 3:xs in xs
-> xs, according to the definition above:
-> 3:xs, where xs = 3:xs
-> 3:xs:xs, where xs = 3:xs
W drugiej postaci wyświetleniu xs
i mogą być dzielone pomiędzy każdymi miejscach występujących, więc myślę, że dlatego możemy wymagać tylko O(1)
spacji zamiast O(n)
. Ale nie jestem pewien, czy mam rację, czy nie.
BTW: słowo kluczowe „shared” pochodzi z tej samej gazety Strona 4:
Problem polega na tym, że standardowe call-by-potrzebie zasady oceny są w stanie rozpoznać, że funkcja:
f = λdt → integralC (1 + dt) (f dt)
jest taka sama, jak:
f = λdt → let x = integralC (1 + dt) x in x
były definicja de fi przyczyny pracować, aby być repea w rekurencyjnym wywołaniu do f, podczas gdy w tym drugim przypadku obliczenia są udostępniane.