以下のコードは、指定された整数 n に対して、リストの最初の n 個の項目を保持し、次の n 個の項目を削除し、次の n 個を保持する、というように続きます。これは、任意の有限リストに対して正しく機能します。
無限リストで使用できるようにするために、「seq」演算子を使用して、例として「foldl」のように再帰ステップの前にアキュムレータの評価を強制しました。
アキュムレータの値をトレースしてテストしたところ、有限リストで必要に応じて効果的に計算されているようです。
ただし、無限リストに適用すると機能しません。メイン関数の「取得」は、内部計算が終了した後にのみ実行されます。もちろん、これは無限リストでは決して起こりません。
誰かが私の間違いを教えてもらえますか?
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