对于给定的整数 n,下面的代码保留列表中的前 n 项,删除后面的 n 项,保留后面的 n 等等。它适用于任何有限列表。
为了使其可用于无限列表,我使用“seq”运算符强制在递归步骤之前进行累加器评估,例如 foldl'。
我通过跟踪累加器的值进行了测试,似乎它是根据有限列表的需要有效计算的。
然而,当应用于无限列表时它不起作用。主函数中的“take”仅在内部计算终止后执行,当然,无限列表永远不会发生这种情况。
拜托,有人能告诉我我的错误在哪里吗?
main :: IO ()
main = print (take 2 (foo 2 [1..100]))
foo :: Show a => Int -> [a] -> [a]
foo l lst = inFoo keepOrNot 1 l lst []
inFoo :: Show a => (Bool -> Int -> [a] -> [a] -> [a]) -> Int -> Int -> [a] -> [a] -> [a]
inFoo keepOrNot i l [] lstOut = lstOut
inFoo keepOrNot i l lstIn lstOut = let lstOut2 = (keepOrNot (odd i) l lstIn lstOut) in
stOut2 `seq` (inFoo keepOrNot (i+1) l (drop l lstIn) lstOut2)
keepOrNot :: Bool -> Int -> [a] -> [a] -> [a]
keepOrNot b n lst1 lst2 = case b of
True -> lst2 ++ (take n lst1)
False -> lst2