循环功能的意外内存使用情况

Tho*_*ing 3 memory haskell cycle

在下面的程序中,我只希望cycle3以恒定的内存运行(它明确地结合了结).然而,cycle2由于我无法理解的原因,也会在恒定的内存中运行.我希望cycle2做完全相同的工作,如cycle1因为

xs' = xs ++ xs'
xs' = xs ++ xs ++ xs' -- substitute value of xs'
xs' = xs ++ xs ++ xs ++ xs' -- substitute value of xs' again
xs' = xs ++ xs ++ xs ++ ... -- and so on
Run Code Online (Sandbox Code Playgroud)

有人可以解释我在这里缺少的东西吗?


module Main where

import System.Environment (getArgs)

cycle1 :: [a] -> [a]
cycle1 [] = error "empty list"
cycle1 xs = xs ++ cycle1 xs

cycle2 :: [a] -> [a]
cycle2 [] = error "empty list"
cycle2 xs = xs' where xs' = xs ++ xs'

cycle3 :: [a] -> [a]
cycle3 [] = error "empty list"
cycle3 xs = let
  xs' = go xs' xs
  in xs'
  where
    go :: [a] -> [a] -> [a]
    go start [last] = last : start
    go start (x:xs) = x : go start xs

testMem :: (Show a) => ([a] -> [a]) -> [a] -> IO ()
testMem f xs = print (xs', xs') -- prints only first val, need second val holds onto reference
  where
    xs' = f xs

main :: IO ()
main = do
  args <- getArgs
  let mCycleFunc = case args of
        ["1"] -> Just cycle1
        ["2"] -> Just cycle2
        ["3"] -> Just cycle3
        _ -> Nothing
  case mCycleFunc of
    Just cycleFunc -> testMem cycleFunc [0..8]
    Nothing -> putStrLn "Valid args are one of {1, 2, 3}."
Run Code Online (Sandbox Code Playgroud)

Lil*_*ard 6

cycle1每次消耗一个周期时都会创建一个新列表.应该是显而易见的原因.

cycle2但是,不这样做.它创建一个变量xs',在自己的定义中使用.在cycle1它不得不重新评估cycle1每次消耗时间的功能xs,但cycle2它不具有任何递归函数.它只引用同一个变量,该变量已具有已知值.