1 --!!! Tests garbage collection in the branch of a case
2 --!!! alternative where the constructor is returned in the heap.
4 {- This is also a rather stressful test for another reason.
5 The mutual recursion between munch and f causes lots of
6 closures to be built, of the form (munch n s), for some n and s.
7 Now, all of these closures are entered and each has as its value
8 the result delivere by the next; so the result is that there is
9 a massive chain of identical updates.
11 As it turns out, they are mostly garbage, so the GC could eliminate
12 them (though this isn't implemented at present), but that isn't
15 The only correct solution is to spot that the updates are all
16 updating with the same value (update frames stacked on top of each
17 other), and update all but one with indirections to the last
18 remaining one. This could be done by GC, or at the moment the
21 Incidentally, hbc won't have this particular problem, because it
24 NOTE: [March 97] Now that stack squeezing happens when GC happens,
25 the stack is squished at GC. So this program uses a small stack
26 in a small heap (eg 4m heap 2m stack), but in a big heap (no GC)
27 it needs a much bigger stack (10m)! It would be better to try GC/stack
28 squeezing on stack oflo.
33 main = munch 100000 (inf 3)
36 = MkStream a a a a a a a a a (Stream a)
39 inf :: Int -> Stream Int
40 inf n = MkStream n n n n n n n n n (inf n)
42 munch :: Int -> Stream a -> IO ()
44 munch n Empty = return () -- error "this never happens!\n"
45 -- this first equation mks it non-strict in "n"
46 -- (NB: call the "error" makes it strict)
48 munch 0 _ = putStr "I succeeded!\n"
49 munch n s = case (f n s) of
51 (False, _) -> error "this never happens either\n"
53 --f :: Int -> Stream a -> (Bool, [Request])
55 f n (MkStream _ _ _ _ _ _ _ _ _ rest)
56 = -- garbage collection *HERE*, please!
57 -- (forced by the closure for n-1)
58 (True, munch (n - 1) rest)
60 -- munch and f are mutually recursive, just to be nasty