Challenge 2: Nested Shadowing, Two Levels Deep — Possible Solution ==================================================================== Main.hs: main :: IO () main = print result where result = let x = 1 -- outermost x, value 1 in let x = x + 10 -- THIS x shadows the outer one... but see below in let x = x * 2 -- innermost x shadows the middle one in x -- (Note: the middle `let x = x + 10` is a deliberately tricky case -- -- Haskell's let bindings are RECURSIVE by default, so the x on the -- right-hand side of that line refers to the binding being defined, -- not the outer one, which would actually cause this specific -- example to loop forever rather than produce 12. A version that -- avoids that trap, actually referencing the OUTER x correctly:) main :: IO () main = print result where outerX = 1 result = let y = outerX + 10 -- explicitly reads outerX, value 1 -> y = 11 in let y = y * 2 -- WOULD also self-reference if reusing y here; -- renaming to z instead to shadow cleanly: in y -- Cleanest demonstration of genuine shadowing without the -- self-reference trap: main :: IO () main = print final where a = 5 -- binding #1 b = let a = 100 -- binding #2, SHADOWS binding #1 inside this let in a + 1 -- refers to binding #2 (100), giving 101 final = a + b -- outer `a` here refers to binding #1 (5) again, since -- binding #2 was only ever visible inside its own `let` Output: 106 Explanation: Inside the `let a = 100 in a + 1` expression, the name `a` refers to the NEW binding (100), giving 101. Once that let expression ends, its shadowing binding goes out of scope entirely -- back in `final`, `a` refers to the original outer binding (5) again, completely unaffected. final = 5 + 101 = 106. WHY THIS WORKS AS AN ANSWER ------------------------------ This demonstrates genuine shadowing (a name reused inside a narrower scope) while correctly avoiding Haskell's own recursive-let self-reference trap, and the explanation correctly traces which binding is in scope at each point, exactly the reasoning the chapter asks for.