haskell - Unexpected memory usage for cycle function -


In the following program, I only expect cycle3 to run with continuous memory The connection is in the form of lump). However, cycle2 also runs in constant memory for reasons because I can not understand. I hope that cycle2 to do the same thing as cycle1

  xs '= xs ++ xs' xs Option of '= xs ++ Xs ++ xs' - xs' xs' = xs + + xs + + xs ++ xs option - xs' then xs option value = xs ++ xs ++ xs ++ .. - - and so on   

Can someone tell me what am I missing?


  Main module where the import system. Environment (getArgs) cycle 1 :: [A] - & gt; [A] circle 1 [] = error "empty list" circle 1 x = xs + cycle 1 xs cycle 2 :: [a] -> gt; [A] circle 2 [] = error "empty list" circle 2 x = xs' where xs' = xs ++ xs' cycle 3 :: [a] -> gt; [A] circle 3 [] = error "blank list" circle 3 x = = x x x 'x in xs xs' where to go: [a] -> [A] - & gt; [A] Start [last] = Last: Start (x: xs) = x: Play xs testMem :: (A) => ([A] - & gt; [A]) - & gt; [A] - & gt; IO () testMem f xs = print (xs', xs') - prints the first value only, the second value is required, where the context is assumed where xs' = f xs main :: IO () main = Do args & lt; - GetArgs mCycleFunc = "[" 1 "] Case Argis -> Simply cycle 1 [" 2 "] -> simply cycle 2 [" 3 "] -> simply cycle 3 _ - & gt; Just cyclone -> Just nothing case mCycleFunc TestMem cycleFunc [0..8] Nothing -> PutStrLn is one of "valid args {1, 2, 3}".   

It comes down to sharing or non-sharing of similar ones. Two similar tights are those As a result, the same result is generated. In the case of Cycle 1 , when you [] at the end of the code , then you are creating a new Think for the cycle1xs > XS . The new memory should be allocated for that thumb, and its value is scratched Should be calculated from the one, which allocates the new list pairs you go through.

I think the way cycle2 is easy to understand by avoiding this It goes that you change the name of the result to xs' (and I delete the "error [] " case ):

  cycle 2 :: [A] - & gt; [A] cycle 2 x = result where result = xs ++ result   

this definition semantically cycle1 (produces the same result for the same logic) Equals, but the key to understanding memory usage is to see what made it. When you execute a compiled code for this function, then it becomes a thumb for the result for exactly that time. You can think of thumb like this, in the form of more or less unstable type (total built pseudocode) in this way:

  type thumbnails a = union {NotDone (ThunkData a) Done a} Type ThunkData A = struct {force :: t0 - & gt; ... - & gt; TN - & gt; A, subthunk0 :: t0, ..., subthunkn :: tn} This is either a record that contains pointers for thumbnails for the required values ​​and an indicator for the code. Which emphasizes them, or the result of just calculating. In the case of  Cycle 2 , the code for the  results  indicates the object code for  (++)  and  xs  and  results . This last bit means that there is an indicator near the Thankbank for  results , which tells continuous space behavior; The last step in compelling the  result  is to point it back to itself.  

In the case of <1> cycle 1 , code for (++) on the other hand in the Thankbank, for xs Begin and calculate new thunk from cycle1 xs . In theory, for the compiler it would be possible to understand that the context of the latter thumb can be replaced with one in the "parent" section, but the compiler does not; While it can not help in cycle2 , but it is a one (a variable = a part to force it immediately).

Keep in mind that this self-referential can be effective in dealing with an appropriate implementation of OK :

  - | Find out at least the definite point of @ F @ This implementation should be created - self-reciprocated chokes, and so on in continuous space. Fix: (A -> A) -> A fine F = result is where the result = f results cycle 4 :: [A] -> gt; [A] cycle 4 x = fine (xs ++)    

Comments